PHP

PHP TutorialCompile PHP ExtensionsContributing to the PHP CoreContributing to the PHP ManualCreate PDF files in PHPInstalling a PHP environment on WindowsPHP Alternative Syntax for Control StructuresPHP APCuPHP Array iterationPHP ArraysPHP Asynchronous programmingPHP Autoloading PrimerPHP BC Math (Binary Calculator)PHP Built in serverPHP CachePHP Classes and ObjectsPHP ClosurePHP Coding ConventionsPHP Command Line Interface (CLI)PHP CommentsPHP Common ErrorsPHP Compilation of Errors and WarningsPHP Composer Dependency ManagerPHP ConstantsPHP Control StructuresPHP CookiesPHP CryptographyPHP DateTime ClassPHP DebuggingPHP Dependency InjectionPHP Design PatternsPHP Docker deploymentPHP Exception Handling and Error ReportingPHP Executing Upon an ArrayPHP File handlingPHP Filters & Filter FunctionsPHP Functional ProgrammingPHP FunctionsPHP GeneratorsPHP Headers ManipulationPHP How to break down an URLPHP How to Detect Client IP AddressPHP HTTP AuthenticationPHP Image Processing with GDPHP ImagickPHP IMAPPHP Installing on Linux/Unix EnvironmentsPHP JSONPHP LocalizationPHP LoopsPHP Machine learningPHP Magic ConstantsPHP Magic MethodsPHP Manipulating an ArrayPHP mongo-phpPHP Multi Threading ExtensionPHP MultiprocessingPHP MySQLiPHP MySQLi affected rows returns 0 when it should return a positive integerPHP NamespacesPHP Object SerializationPHP OperatorsPHP Output BufferingPHP Outputting the Value of a VariablePHP Parsing HTMLPHP Password Hashing FunctionsPHP PDOPHP PerformancePHP PHPDocPHP Processing Multiple Arrays TogetherPHP PSRPHP Reading Request DataPHP RecipesPHP ReferencesPHP ReflectionPHP Regular Expressions (regexp/PCRE)PHP Secure Remeber MePHP SecurityPHP Sending EmailPHP SerializationPHP SessionsPHP SimpleXMLPHP SOAP ClientPHP SOAP ServerPHP SocketsPHP SPL data structuresPHP SQLite3PHP StreamsPHP String formattingPHP String Parsing



PHP Sockets

From WikiOD

TCP client socket[edit | edit source]

Creating a socket that uses the TCP (Transmission Control Protocol)[edit | edit source]

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Make sure the socket is successfully created. The onSocketFailure function comes from Handling socket errors example in this topic.

if(!is_resource($socket)) onSocketFailure("Failed to create socket");

Connect the socket to a specified address[edit | edit source]

The second line fails gracefully if connection failed.

socket_connect($socket, "chat.stackoverflow.com", 6667)
        or onSocketFailure("Failed to connect to chat.stackoverflow.com:6667", $socket);

Sending data to the server[edit | edit source]

The socket_write function sends bytes through a socket. In PHP, a byte array is represented by a string, which is normally encoding-insensitive.

socket_write($socket, "NICK Alice\r\nUSER alice 0 * :Alice\r\n");

Receiving data from the server[edit | edit source]

The following snippet receives some data from the server using the socket_read function.

Passing PHP_NORMAL_READ as the third parameter reads until a \r/\n byte, and this byte is included in the return value.

Passing PHP_BINARY_READ, on the contrary, reads the required amount of data from the stream.

If socket_set_nonblock was called in prior, and PHP_BINARY_READ is used, socket_read will return false immediately. Otherwise, the method blocks until enough data (to reach the length in the second parameter, or to reach a line ending) are received, or the socket is closed.

This example reads data from a supposedly IRC server.

while(true) {
    // read a line from the socket
    $line = socket_read($socket, 1024, PHP_NORMAL_READ);
    if(substr($line, -1) === "\r") {
        // read/skip one byte from the socket
        // we assume that the next byte in the stream must be a \n.
        // this is actually bad in practice; the script is vulnerable to unexpected values
        socket_read($socket, 1, PHP_BINARY_READ);
    }

    $message = parseLine($line);
    if($message->type === "QUIT") break;
}

Closing the socket[edit | edit source]

Closing the socket frees the socket and its associated resources.

socket_close($socket);

TCP server socket[edit | edit source]

Socket creation[edit | edit source]

Create a socket that uses the TCP. It is the same as creating a client socket.

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

Socket binding[edit | edit source]

Bind connections from a given network (parameter 2) for a specific port (parameter 3) to the socket.

The second parameter is usually "0.0.0.0", which accepts connection from all networks. It can also

One common cause of errors from socket_bind is that the address specified is already bound to another process. Other processes are usually killed (usually manually to prevent accidentally killing critical processes) so that the sockets would be freed.

socket_bind($socket, "0.0.0.0", 6667) or onSocketFailure("Failed to bind to 0.0.0.0:6667");

Set a socket to listening[edit | edit source]

Make the socket listen to incoming connections using socket_listen. The second parameter is the maximum number of connections to allow queuing before they are accepted.

socket_listen($socket, 5);

Handling connection[edit | edit source]

A TCP server is actually a server that handles child connections. socket_accept creates a new child connection.

$conn = socket_accept($socket);

Data transferring for a connection from socket_accept is the same as that for a TCP client socket.

When this connection should be closed, call socket_close($conn); directly. This will not affect the original TCP server socket.

Closing the server[edit | edit source]

On the other hand, socket_close($socket); should be called when the server is no longer used. This will free the TCP address as well, allowing other processes to bind to the address.

UDP server socket[edit | edit source]

A UDP (user datagram protocol) server, unlike TCP, is not stream-based. It is packet-based, i.e. a client sends data in units called "packets" to the server, and the client identifies clients by their address. There is no builtin function that relates different packets sent from the same client (unlike TCP, where data from the same client are handled by a specific resource created by socket_accept). It can be thought as a new TCP connection is accepted and closed every time a UDP packet arrives.

Creating a UDP server socket[edit | edit source]

$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

Binding a socket to an address[edit | edit source]

The parameters are same as that for a TCP server.

socket_bind($socket, "0.0.0.0", 9000) or onSocketFailure("Failed to bind to 0.0.0.0:9000", $socket);

Sending a packet[edit | edit source]

This line sends $data in a UDP packet to $address:$port.

socket_sendto($socket, $data, strlen($data), 0, $address, $port);

Receiving a packet[edit | edit source]

The following snippet attempts to manage UDP packets in a client-indexed manner.

$clients = [];
while (true){
    socket_recvfrom($socket, $buffer, 32768, 0, $ip, $port) === true
            or onSocketFailure("Failed to receive packet", $socket);
    $address = "$ip:$port";
    if (!isset($clients[$address])) $clients[$address] = new Client();
    $clients[$address]->handlePacket($buffer);
}

Closing the server[edit | edit source]

socket_close can be used on the UDP server socket resource. This will free the UDP address, allowing other processes to bind to this address.

Handling socket errors[edit | edit source]

socket_last_error can be used to get the error ID of the last error from the sockets extension.

socket_strerror can be used to convert the ID to human-readable strings.

function onSocketFailure(string $message, $socket = null) {
    if(is_resource($socket)) {
        $message .= ": " . socket_strerror(socket_last_error($socket));
    }
    die($message);
}

Credit:Stack_Overflow_Documentation