These Socket functions directly communicate with the Internet protocol to send information. Compared with fopensock's streams, they operate at a relatively low level. Usually, they encapsulate C functions and have similar names. If you have experience with socket programming in C, you will be very comfortable using these functions. We will not discuss socket programming in special detail here.
Use these functions to solve difficult problems that higher-level functions cannot. Using these functions can achieve functions similar to fopen. You may have many ways to implement socket functions, such as the Internet daemon implemented using CLI (Command-line Interface) in PHP.
resource socket_accept(resource socket)
In the server side of your script, use socket_accept to accept an incoming connection. You must first create a socket, bind it to a name, and set it to listen on a port. In block mode, socket_accept will generate a unique accepted connection. In non-block mode, it returns false if no connection is established. In addition, when you have a new socket resource, you can perform read and write operations.
Below we will demonstrate a simple echo server. It runs under the CLI (command line), and it waits for client connections on port 12345.
socket_accept
<?php
set_time_limit(0);
//create the socket
if(($socket = socket_create(AF_INET, SOCK_STREAM, 0)) < 0){
print("Couldn't create socket: " . socket_strerror(socket_last_error()) . "n");
}
//bind it to the given address and port
if(($error = socket_bind($socket, gethostbyname($_SERVER['HOSTNAME']), 12345)) < 0){
print("Couldn't bind socket: " . socket_strerror(socket_last_error()) . "n");
}
if(($error = socket_listen($socket, 5)) < 0){
print("Couldn't list on socket: " .
socket_strerror(socket_last_error()) . "n");
}
while(TRUE){
//wait for connection
if(($accept = socket_accept($socket)) < 0){
print("Error while reading: " . socket_strerror($message) . "n");
break;
}
//send welcome message
socket_write($accept, "Connection acceptedn");
print(date('Ymd H:i:s') . " STATUS: Connection acceptedn");
ob_flush();
while(TRUE){
//read line from client
if(FALSE === ($line = socket_read($accept, 1024))){
print("Couldn't read from socket: " .
socket_strerror(socket_last_error()) . "n");
break 2;
}
if( !@socket_write($accept , "ECHO: $line")){
print(date('Ymd H:i:s') . " STATUS: Connection interruptedn");
break;
}
print(date('Ymd H:i:s') . " READ: $line");
ob_flush();
}
socket_close($accept);
}
?>
bool socket_bind(resource socket, string address, integer port)
This socket_bind() binds a socket resource to an address. This socket must be a resource returned by the socket_create() function. This address must be an IP address or a path to a Unix socket. If it is a socket running on the Internet, you must also provide a port.
socket_clear_error(resource socket)
This function can clear errors for the specified socket. If no parameters are specified, all socket errors will be cleared.
socket_close(resource socket)
The socket_close function closes a socket and clears the memory resources occupied by the socket.
boolean socket_connect(resource socket, string address, integer port)
This function creates a client connection to a port or socket. You must provide a socket generated by socket_create. The address parameter must be the path to a socket or an IP address. If it is the latter, it must also be followed by a numeric port number.
The following example demonstrates the process of connecting to the game server and obtaining information using the UDP protocol.
socket_connect
<?php
//create UDP socket
if(($socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) < 0){
print("Couldn't create socket: " .
socket_strerror(socket_last_error()) . "n");
}
//timeout after 5 seconds
socket_set_option($socket, SOL_SOCKET,
SO_RCVTIMEO, array('sec'=>5,'usec'=>0));
//connect to the RtCW master server
if(!socket_connect($socket, 'wolfmaster.idsoftware.com', 27950)){
print("Couldn't connect: " .
socket_strerror(socket_last_error()) . "n");
}
//send request for servers
socket_write($socket, "xFFxFFxFFxFFgetserversx00");
//get servers
$server = array();
while(FALSE !== ($line = @socket_read($socket, 4096))){
//parse data
for($i=22; ($i+5) < strlen($line); $i += 7){
$ip = ord(substr($line, $i+1, 1)) . '.' .
ord(substr($line, $i+2, 1)) . '.' .
ord(substr($line, $i+3, 1)) . '.' .
ord(substr($line, $i+4, 1));
$port = (ord(substr($line, $i+5, 1)) * 256) +
ord(substr($line, $i+6, 1));
$server[] = array('ip'=>$ip, 'port'=>$port);
}
}
print("<h1>" . count($server) . " Servers</h1>n");
//loop over servers, getting status
foreach($server as $s){
print("<h1>{$s['ip']}:{$s['port']}</h1>n");
//connect to RtCW server
if(!socket_connect($socket, $s['ip'], $s['port'])){
print("<p>n" .
socket_strerror(socket_last_error()) .
"n</p>n");
continue;
}
//send request for status
socket_write($socket, "xFFxFFxFFxFFgetstatusx00");
//get status from server
if(FALSE === ($line = @socket_read($socket, 1024))){
print("<p>n" .
socket_strerror(socket_last_error()) .
"n</p>n");
continue;
}
$part = explode("n", $line);
//settings are in second line separated by backslashes
$setting = explode("\", $part[1]);
print("<h2>Configuration</h2>n");
print("<p>n");
for($s=1; $s < count($setting); $s += 2){
print("tt{$setting[$s]} = {$setting[$s+1]}<br>n");
}
print("</p>n");
print("<h2>Players</h2>n");
$lastPlayer = count($part) - 1;
for($p=2; $p < $lastPlayer; $p++){
$player = explode(" ", $part[$p]);
print("{$player[2]} Score={$player[0]} " .
"Ping={$player[1]}<br>n");
}
print("</p>n");
ob_flush();
}
print("</table>n");
socket_close($socket);
?>
resource socket_create(integer family, integer socket_type, integer protocol)
socket_create initializes a socket structure. The first parameter is a protocol family, or domain. You must use AF_INET to specify an Internet connection, or AF_UNIX to specify a Unix socket connection. The second parameter is a socket type, which you can choose from the table below. Generally, use SOCK_STREAM to use the TCP protocol, and the UDP protocol to use SOCK_DGRAM. The third parameter specifies a protocol. Use SOL_TCP or SOL_UDP to correspond to TCP and UDP protocols respectively. Another option is that you can use the getprotobyname function to handle this.
Socket type constant description
SOCK_DGRAM automatically addresses packet socket
SOCK_RAW RAW protocol interface
SOCK_RDM reliable exchange of messages
SOCK_SEQPACKET sequential data packet socket
SOCK_STREAM stream socket
resource socket_create_listen(integer port, integer backlog)
Using socket_create_listen is a simpler method than socket_create to generate a socket for listening. The generated socket will listen to the specified port, and the optional parameter backlog is to set the maximum number of connections allowed.
boolean socket_create_pair(integer family, integer socket_type, integer protocol, array handles)
The socket_create_pair function generates a pair of socket connections. First of all, the first three parameters are a description of a socket_create. The handles parameter is an array containing two socket resources. This function is an encapsulation of the socketpair function in C.
socket_create_pair
<?php
if(!socket_create_pair(AF_UNIX, SOCK_STREAM, 0, $socket)){
print("Couldn't make sockets!n");
exit();
}
$child = pcntl_fork();
if($child == -1){
print("Couldn't fork!n");
exit();
}
elseif($child > 0){
//parent
socket_close($socket[0]);
print("Parent: waiting for messagen");
$message = socket_read($socket[1], 1024, PHP_NORMAL_READ);
print("Parent: got message--$messagen");
socket_write($socket[1], "Hello, Child Process!n");
pcntl_waitpid($child, $status);
}else{
//child
socket_close($socket[1]);
socket_write($socket[0], "Hello, Parent Process!n");
print("Child: waiting for messagen");
$message = socket_read($socket[0], 1024, PHP_NORMAL_READ);
print("Child: got message--$messagen");
exit(0);
}
?>
value socket_get_option(resource socket, integer level, integer option)
The socket_get_option function returns an added value listed in the following table. You must provide a socket resource generated by socket_create and a level. This obtained socket level can be determined using SOL_SOCKET. Alternatively, use a protocol such as SOL_TCP to represent a TCP protocol. These options may be set by socket_set_option.
socket_get_options
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
print('SO_BROADCAST: ' .
socket_get_option($socket, SOL_SOCKET,
SO_BROADCAST) . "<br>n");
print('SO_DEBUG: ' .
socket_get_option($socket, SOL_SOCKET,
SO_DEBUG) . "<br>n");
print('SO_DONTROUTE: ' .
socket_get_option($socket, SOL_SOCKET,
SO_DONTROUTE) . "<br>n");
print('SO_ERROR: ' .
socket_get_option($socket, SOL_SOCKET,
SO_ERROR) . "<br>n");
print('SO_KEEPALIVE: ' .
socket_get_option($socket, SOL_SOCKET,
SO_KEEPALIVE) . "<br>n");
print('SO_LINGER: ' .
print_r(socket_get_option($socket, SOL_SOCKET,
SO_LINGER), TRUE) . "<br>n");
print('SO_OOBINLINE: ' .
socket_get_option($socket, SOL_SOCKET,
SO_OOBINLINE) . "<br>n");
print('SO_RCVBUF: ' .
socket_get_option($socket, SOL_SOCKET,
SO_RCVBUF) . "<br>n");
print('SO_RCVLOWAT: ' .
socket_get_option($socket, SOL_SOCKET,
SO_RCVLOWAT) . "<br>n");
print('SO_RCVTIMEO: ' .
print_r(socket_get_option($socket, SOL_SOCKET,
SO_RCVTIMEO), TRUE) . "<br>n");
print('SO_REUSEADDR: ' .
socket_get_option($socket, SOL_SOCKET,
SO_REUSEADDR) . "<br>n");
print('SO_SNDBUF: ' .
socket_get_option($socket, SOL_SOCKET,
SO_SNDBUF) . "<br>n");
print('SO_SNDLOWAT: ' .
socket_get_option($socket, SOL_SOCKET,
SO_SNDLOWAT) . "<br>n");
print('SO_SNDTIMEO: ' .
print_r(socket_get_option($socket, SOL_SOCKET,
SO_SNDTIMEO), TRUE) . "<br>n");
print('SO_TYPE: ' .
socket_get_option($socket, SOL_SOCKET,
SO_TYPE) . "<br>n");
?>
Socket option table option description
SO_BROADCAST allows automatically addressed sockets to send and receive broadcast packets
SO_DEBUG turns on the socket debugging function. Only root has the permission to turn on this option.
SO_DONTROUTE does not accept routing packets through the gateway
SO_ERROR Gets and clears the last socket error. This option may not need to be set.
SO_KEEPALIVE Open a message that remains active
SO_LINGER Socket_colse and socket_shutdown abort message sending timeout, this option uses an array, including the two keys l_onoff and l_linger.
SO_OOBINLINE inserts data directly into the receiving buffer
SO_RCVBUF limits the maximum number of bytes that can be buffered
SO_RCVLOWAT delays by accepting a minimum data
SO_RCVTIMEO Delays reporting of an accept timeout, using two keys of the array: sec and usec
SO_REUSEADDR allows reuse of local addresses
SO_SNDBUF limits the maximum bytes of the send buffer
SO_SNDLOWAT delays sending data to this protocol while accepting a minimum of bytes
SO_SNDTIMEO Delays reporting of timeout errors when a sender passes a timeout. This option uses the keys of the array: sec and usec
SO_TYPE Gets the type of socket. This option may not need to be set.
boolean socket_getpeername(resource socket, string address, integer port)
socket_getpeername obtains the address and port from a specified connection. If the connection is a Unix socket, the path to the file system will be returned.
boolean socket_getsockname(resource socket, string address, integer port)
socket_getsockname places a name into the socket and adds the address and port parameters. Returns false on failure.
(I don’t know much about the socket_iovec_* functions below, so I don’t dare to translate them randomly, so I keep the original text)
boolean socket_iovec_add(resource iovector, integer length)
The socket_iovec_add unction adds an I/O vector to the scatter/gather array.
resource socket_iovec_alloc(integer count, …)
The socket_iovec_alloc function returns a resource for handling a collection of I/O vectors. The first argument specifies the number of vectors. Following arguments specify the length of each vector.
boolean socket_iovec_delete(resource iovector, integer position)
The socket_iovec_delete function removes the I/O vector at the given position.
string socket_iovec_fetch(resource iovector, integer position)
The socket_iovec_fetch function returns the value of the specified vector in the I/O vector resource.
boolean socket_iovec_free(resource iovector)
The socket_iovec_free function frees the memory used for an I/O vector resource.
boolean socket_iovec_set(resource iovector, integer position, string value)
The socket_iovec_set sets the value of I/O vector at the given position.
integer socket_last_error(resource socket)
The socket_last_error function returns the last error generated by any socket function in the operation. You may have set the socket option of the socket resource on the specified connection in the above function. The following table lists the error codes returned. You can also use the soclet_strerror function to obtain detailed errors. Use the socket_clear_error function to clear socket errors.
Socket error code table constant description
SOCKET_E2BIG parameter list too long
SOCKET_EACCES has no permission
SOCKET_EADDRINUSE address is already in use
SOCKET_EADDRNOTAVAIL cannot resolve the requested address
SOCKET_EADV broadcast (advertisement) error
SOCKET_EAFNOSUPPORT Protocol not supported by Address family
SOCKET_EAGAIN resource is temporarily unavailable
SOCKET_EALREADY operation is already executing
SOCKET_EBADE Invalid exchange
SOCKET_EBADF bad file descriptor
SOCKET_EBADFD file descriptor error status
SOCKET_EBADMSG error message
SOCKET_EBADR Invalid request description
SOCKET_EBADRQC Invalid request code
SOCKET_EBADSLT Invalid operation location
SOCKET_EBUSY The driver or resource is busy
SOCKET_ECHRNG channel number out of range
SOCKET_ECOMM Send communication error
SOCKET_ECONNABORTED Traffic interruption due to software reasons
SOCKET_ECONNREFUSED connection refused
SOCKET_ECONNRESET The connection is reset by the same socket
SOCKET_EDESTADDRREQ must require the destination address
SOCKET_EDQUOT disk quota exceeded
SOCKET_EEXIST file already exists
SOCKET_EFAULT wrong address
SOCKET_EHOSTDOWN host is down
SOCKET_EHOSTUNREACH is not routed to the host
SOCKET_EIDRM indicates that the ID has been deleted
SOCKET_EINPROGRESS operation is executing
SOCKET_EINTR system call blocked
SOCKET_EINVAL invalid parameter
SOCKET_EIO input/output error
SOCKET_EISCONN transmission terminal has been connected
SOCKET_EISDIR is a directory
SOCKET_EISNAM is a specified type file
SOCKET_EL2HLT Level 2 aborted
SOCKET_EL2NSYNC Level 2 out of sync
SOCKET_EL3HLT Level 3 aborted
SOCKET_EL3RST Level 3 is reset
SOCKET_ELNRNG connection number is out of range
SOCKET_ELOOP Too many levels of symbolic links
SOCKET_EMEDIUMTYPE Wrong media type (intermediate type)
SOCKET_EMFILE Too many open files
SOCKET_EMLINK Too many connections
SOCKET_EMSGSIZE message is too long
SOCKET_EMULTIHOP Too many attempts
SOCKET_ENAMETOOLONG file name too long
SOCKET_ENETDOWN network is down
SOCKET_ENETRESET The network was interrupted and the connection was reset.
SOCKET_ENETUNREACHThe network is unreachable
SOCKET_ENFILE Too many open files in the system
SOCKET_ENOANO No positive pole
SOCKET_ENOBUFS No cache space available
SOCKET_ENOCSI No CSI structure available
SOCKET_ENODATA No data available
SOCKET_ENODEV No such driver
SOCKET_ENOENT No such file or directory
SOCKET_ENOLCK No record lock available
SOCKET_ENOLINK connection to an existing service
SOCKET_ENOMEDIUM No medium found
SOCKET_ENOMEM cannot allocate memory
SOCKET_ENOMSG No specified message type
SOCKET_ENONET device is not on the network
SOCKET_ENOPROTOOPT protocol is not available
SOCKET_ENOSPC No space in drive
SOCKET_ENOSR exceeded stream resource
SOCKET_ENOSTR driver is not a stream
SOCKET_ENOSYS function is not executed
SOCKET_ENOTBLK block driver is required
SOCKET_ENOTCONN The transmission terminal is not connected
SOCKET_ENOTDIR does not have a directory
SOCKET_ENOTEMPTY directory is empty
SOCKET_ENOTSOCK Socket operation on a non-socket
SOCKET_ENOTTY Incompatible IO controller
SOCKET_ENOTUNIQ name is not unique on the network
SOCKET_ENXIO No such driver or address
SOCKET_EOPNOTSUPP operation is not supported
SOCKET_EPERM operation not allowed
SOCKET_EPFNOSUPPORT Protocol family is not supported
SOCKET_EPIPE failed pipe
SOCKET_EPROTO protocol error
SOCKET_EPROTONOSUPPORT protocol is not supported
SOCKET_EPROTOTYPE The type of protocol error on the Socket
SOCKET_EREMCHG remote address has changed
SOCKET_EREMOTE object is remote
SOCKET_EREMOTEIO remote I/O error
SOCKET_ERESTART The interrupted system call will be restarted
SOCKET_EROFS file system is read-only
SOCKET_ESHUTDOWN. Transmission endpoint interrupt cannot be sent
SOCKET_ESOCKTNOSUPPORT Socket type is not supported
SOCKET_ESPIPE illegal search
SOCKET_ESTRPIPE stream pipe error
SOCKET_ETIME timer expires
SOCKET_ETIMEDOUT connection timeout
SOCKET_ETOOMANYREFS Too many connections to combine
SOCKET_EUNATCH Unable to attach protocol driver
SOCKET_EUSERS Too many users
SOCKET_EWOULDBLOCK resource is temporarily unavailable
SOCKET_EXDEV Invalid cross-drive connection
SOCKET_EXFULL exchange is full
boolean socket_listen(resource socket, integer backlog)
This socket_listen function waits for connections from the client. The backlog parameter sets the maximum number of queues allowed to wait for connections.
string socket_read(resource socket, integer length, integer type)
The socket_read function reads the specified bytes from a specific socket and returns false if there is an error. By default, binary-safe read mode is used. You can change the read mode by externally setting the type parameter to PHP_BINARY_READ. You can also set type to PHP_NORMAL_READ.
boolean socket_readv(resource socket, resource iovector)
The socket_readv function inserts the read data into the iovector resource.
integer socket_recv(resource socket, string buffer, integer length, integer flags)
The socket_recv function reads data and inserts it into the buffer. The Length parameter sets the maximum number of bytes to read, and the flag parameter can use MSG_OOB or MSG_PEEK. The function returns the number of bytes read.
integer socket_recvfrom(resource socket, string buffer, integer length, string host, integer port)
The socket_frcvfrom function reads data and inserts it into the cache. The Length parameter sets the maximum number of bytes allowed to be received. The flags parameter can be set to MSG_OOB or MSG_PEEK. PHP sets the host and port parameters to appropriate values to be able to obtain data sent from the host.
boolean socket_recvmsg(resource socket, resource iovector, array control, integer length, integer flags, string host, integer port)
The socket_recvmsg function reads data from the socket and inserts it into an I/O vector resource. The PHP setting control parameter is an associative array with three elements: cmsg_level, cmsg_type, and cmsg_data. The Length parameter is a length parameter attached to the data about obtaining the data. The Flags parameter sets the allowed values and return values. At the time of writing, PHP cannot execute all output constants. PHP sets the host and port parameters to appropriate values in order to obtain data sent from the remote host.
(The Socket_slect function is not translated because I am afraid that the words do not convey the meaning)
integer socket_select(array read, array write, array exception, integer timeout_seconds, integer timeout_microseconds)
The socket_select function waits for changes to sockets. PHP watches the sockets given in the read array for new data coming in. PHP watches the streams given in the write array for being ready to accept more data. PHP watches the streams given in the exception argument for errors. If the number of seconds specified in the timeout_seconds argument passes, the function returns. Use the optional timeout_microseconds argument to specify a timeout less than 1 second.
The socket_select function returns the number of sockets that changed or FALSE if an error occurred. If the call timed out, this function returns zero. It also modifies the given arrays so that they include only those sockets that changed.
If you have no sockets of a particular type to watch, you may pass an empty array or a variable set to NULL.
integer socket_send(resource socket, string buffer, integer length, integer flags)
The socket_send function writes data to the buffer and then inserts it into the connection. You must specify a maximum number of writeable bytes for the buffer. You can also set the flags parameter to empty, or to one of the following combined constants: MSG_DONTROUTE and MSG_OOB. The function ends and returns the number of bytes written, otherwise it returns false.
boolean socket_sendmsg(resource socket, resource iovector, integer flags, string address, integer port)
socket_sendmsg attempts to send data to a socket. It is suitable for connectionless sockets. The Iovector parameter is a resource generated by the socket_iovec_alloc function. You must specify the flags parameter as: NULL, MSG_DONTROUTE, MSG_OOB, or two combined constants. You should specify an address and a port for Internet requests.
The Socket_sendmsg function returns true when sending data, but there is no guarantee that the data will arrive.
integer socket_sendto(resource socket, string buffer, integer length, integer flags, string address, integer port)
The socket_sendto function attempts to write data to the buffer and send it to a socket. It is suitable for most connectionless sockets. You must specify flags as: NULL, MSG_DONTROUTE, MSG_OOB or a combination of two constants. You should also specify the address and a requested port.
The Socket_sendto function returns true when data is sent, but there is no guarantee that the data will arrive.
boolean socket_set_block(resource socket)
The socket_set_block function sets the socket into a block mode, which is the default mode. In block mode, I/O operations are performed on a completed request.
boolean socket_set_nonblock(resource socket)
The socket_set_nonblock function sets the socket to be inserted into any non-block mode. In non-block mode, I/O operations return immediately, even if there is no data.
boolean socket_set_option(resource socket, integer level, integer option, integer value)
The socket_set_option function sets an option for the socket. The Level parameter sets a constant that flags the level. Valid values include: SOL_SOCKET, SOL_TCP and SOL_UDP. The Option parameters must match the constants in the Socket options table above.
boolean socket_shutdown(resource socket, integer how)
The socket_shutdown function closes a socket for I/O. Setting how to 0 will stop receiving data, setting it to 1 will stop sending data, and setting it to 2 will stop both operations.
string socket_strerror(integer error)
The socket_strerror function returns an error number and detailed error information.
integer socket_write(resource socket, string buffer, integer length)
The socket_write function writes data to the buffer and then outputs it to the socket. You can specify the length parameter to specify the maximum number of bytes in the buffer. This function is usually more convenient than socket_send.
boolean socket_writev(resource socket, resource iovector)
The socket_writev function writes data to a socket through I/O vectors.