update page now
Longhorn PHP 2026 - Call For Papers

Voting

: min(five, seven)?
(Example: nine)

The Note You're Voting On

juanfe0245 at gmail dot com
6 years ago
<?php
//Creamos un socket de transmisión de tipo TCP / IP.
$servidorSocket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//Configuramos la opción para reutilizar el puerto.
socket_set_option($servidorSocket,SOL_SOCKET,SO_REUSEADDR,1);
/*
    Vinculamos el socket a nuestro puerto y dirección IP.
    Ahora, todas las conecciones en este puerto son nuestro responsabilidad para recibir y enviar datos.
*/
socket_bind($servidorSocket,'localhost',9000);
//Comenzamos a escuchar conexiones.
socket_listen($servidorSocket);
/*
    Creamos un arreglo con todos los clientes que se conectarán a nuestro servidor.
    Añadimos nuestro socket servidor al arreglo de clientes.
*/
$clientes=[$servidorSocket];
$null=null;
while(true){
    //Creamos una copia de $clientes, debido a que $clientes no se modifica por la función socket_select().
    $nuevoClienteLector=$clientes;
    //Obtenemos una lista de todos los clientes que tienen datos para leer.
    socket_select($nuevoClienteLector,$null,$null,10);
    //Verificamos si hay un cliente tratando de conectarse.
    if(in_array($servidorSocket,$nuevoClienteLector)){
        //Aceptamos el cliente y lo añadimos al arreglo de $clientes.
        $nuevoCliente=socket_accept($servidorSocket);
        echo "Socket aceptado.\n";
        $clientes[]=$nuevoCliente;
        //Obtenemos el encabezado del cliente y realizamos la comprobación del handshake.
        $encabezado=socket_read($nuevoCliente,1024);
        handshake($nuevoCliente,$encabezado);
        //Eliminamos el cliente del arreglo $nuevoClienteLector.
        $nuevoClienteIndex=array_search($servidorSocket,$nuevoClienteLector);
        unset($nuevoClienteLector[$nuevoClienteIndex]);
    }
    //Recorremos todos los clientes que tienen datos por leer.
    foreach($nuevoClienteLector as $cliente){
        //Recibimos información del cliente conectado.
        while(socket_recv($cliente,$datosCliente,1024,0)>=1){
            //Decodificamos el mensaje que viene en bytes.
            $mensaje=decodificar($datosCliente);
            //Enviamos el mensaje a todos los sockets conectados.
            enviar($clientes,$mensaje);
            echo $mensaje."\n";
            break 2;
        }
        //Verificamos si el cliente esta desconectado.
        $datosCliente=@socket_read($cliente,1024,PHP_NORMAL_READ);
        if($datosCliente===false){
            $clienteIndex=array_search($cliente,$clientes);
            //Eliminamos el cliente del arreglo $clientes.
            unset($clientes[$clienteIndex]);
            echo "Cliente desconectado.\n";
        }
    }
}
function enviar($clientes,$mensaje){
    $mensaje=codificar($mensaje);
    foreach($clientes as $cliente){
        @socket_write($cliente,$mensaje,strlen($mensaje));
    }
}
socket_close($servidorSocket);
function codificar($socketData){
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($socketData);
    
    if($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCn', $b1, 126, $length);
    elseif($length >= 65536)
        $header = pack('CCNN', $b1, 127, $length);
    return $header.$socketData;
}
function decodificar($socketData) {
    $length = ord($socketData[1]) & 127;
    if($length == 126) {
        $masks = substr($socketData, 4, 4);
        $data = substr($socketData, 8);
    }
    elseif($length == 127) {
        $masks = substr($socketData, 10, 4);
        $data = substr($socketData, 14);
    }
    else {
        $masks = substr($socketData, 2, 4);
        $data = substr($socketData, 6);
    }
    $socketData = "";
    for ($i = 0; $i < strlen($data); ++$i) {
        $socketData .= $data[$i] ^ $masks[$i%4];
    }
    return $socketData;
}
function handshake($client_socket_resource,$received_header) {
    $headers = array();
    $lines = preg_split("/\r\n/", $received_header);
    foreach($lines as $line){
        $line = chop($line);
        if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)) $headers[$matches[1]] = $matches[2];
    }
    $secKey = $headers['Sec-WebSocket-Key'];
    $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
    $buffer  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
    "Upgrade: websocket\r\n" .
    "Connection: Upgrade\r\n" .
    "Sec-WebSocket-Accept:$secAccept\r\n\r\n";
    socket_write($client_socket_resource,$buffer,strlen($buffer));
}

<< Back to user notes page

To Top