Buscar..


Socket cliente TCP

Creando un socket que usa el TCP (Protocolo de Control de Transmisión)

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

Asegúrese de que el zócalo se haya creado correctamente. La función onSocketFailure proviene del ejemplo Manejo de errores de socket en este tema.

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

Conecte el zócalo a una dirección especificada

La segunda línea falla con gracia si falla la conexión.

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

Enviando datos al servidor

La función socket_write envía bytes a través de un socket. En PHP, una matriz de bytes está representada por una cadena, que normalmente es insensible a la codificación.

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

Recibiendo datos del servidor

El siguiente fragmento de socket_read recibe algunos datos del servidor mediante la función socket_read .

Al pasar PHP_NORMAL_READ como el tercer parámetro se lee hasta un byte \r / \n , y este byte se incluye en el valor de retorno.

Al pasar PHP_BINARY_READ , por el contrario, lee la cantidad requerida de datos de la secuencia.

Si socket_set_nonblock fue llamado antes, y PHP_BINARY_READ se utiliza, socket_read volverá false inmediatamente. De lo contrario, el método se bloquea hasta que se reciben suficientes datos (para alcanzar la longitud en el segundo parámetro, o para alcanzar un final de línea), o se cierra el zócalo.

Este ejemplo lee datos de un servidor supuestamente IRC.

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;
}

Cerrando el zócalo

Cerrar el socket libera el socket y sus recursos asociados.

socket_close($socket);

Zócalo del servidor TCP

Creación de zócalo

Crea un socket que use el TCP. Es lo mismo que crear un socket de cliente.

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

Enlace de zócalo

Enlace las conexiones de una red dada (parámetro 2) para un puerto específico (parámetro 3) al socket.

El segundo parámetro suele ser "0.0.0.0" , que acepta la conexión de todas las redes. También puede

Una causa común de errores de socket_bind es que la dirección especificada ya está vinculada a otro proceso . Otros procesos generalmente se eliminan (generalmente de forma manual para evitar la muerte accidental de procesos críticos) para que los sockets se liberen.

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

Establecer un zócalo para escuchar.

Haz que el socket escuche las conexiones entrantes usando socket_listen . El segundo parámetro es el número máximo de conexiones para permitir la puesta en cola antes de que sean aceptadas.

socket_listen($socket, 5);

Manejo de conexion

Un servidor TCP es en realidad un servidor que maneja conexiones secundarias. socket_accept crea una nueva conexión secundaria.

$conn = socket_accept($socket);

La transferencia de datos para una conexión desde socket_accept es la misma que para un socket de cliente TCP .

Cuando se debe cerrar esta conexión, llame a socket_close($conn); directamente. Esto no afectará el socket del servidor TCP original.

Cerrando el servidor

Por otro lado, socket_close($socket); debe llamarse cuando el servidor ya no se utiliza. Esto también liberará la dirección TCP, permitiendo que otros procesos se unan a la dirección.

Manejo de errores de socket

socket_last_error se puede usar para obtener el ID de error del último error de la extensión de sockets.

socket_strerror se puede usar para convertir el ID en cadenas legibles para el usuario.

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

Servidor UDP socket

Un servidor UDP (protocolo de datagramas de usuario), a diferencia de TCP, no está basado en flujo. Se basa en paquetes, es decir, un cliente envía datos en unidades denominadas "paquetes" al servidor, y el cliente identifica a los clientes por su dirección. No hay una función incorporada que relacione diferentes paquetes enviados desde el mismo cliente (a diferencia de TCP, donde los datos del mismo cliente son manejados por un recurso específico creado por socket_accept ). Puede pensarse como una nueva conexión TCP es aceptada y cerrada cada vez que llega un paquete UDP.

Creando un socket de servidor UDP

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

Atar un socket a una dirección

Los parámetros son los mismos que para un servidor TCP.

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

Enviando un paquete

Esta línea envía $data en un paquete UDP a $address : $port .

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

Recibiendo un paquete

El siguiente fragmento de código intenta administrar paquetes UDP de una manera indexada por el cliente.

$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);
}

Cerrando el servidor

socket_close se puede utilizar en el recurso de socket del servidor UDP. Esto liberará la dirección UDP, permitiendo que otros procesos se unan a esta dirección.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow