一个或多个保留位打开:reserved1 = 0、reserved2 = 1、reserved3 = 1

Dav*_*ini 5 html javascript network-programming websocket phpwebsocket

在 Chrome 中 50.0.2661.94 m

\n\n
var a = new WebSocket(\'ws://192.168.0.153:9000/socket_listener_1_WINDOWS.php\');\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误(从昨天下午开始 - 它适用于其他客户端电脑,但“ws://echo.websocket.org/”也可以使用我的电脑作为客户端)

\n\n
WebSocket connection to \'ws://192.168.0.153:9000/socket_listener_1_WINDOWS.php\' failed: One or more reserved bits are on: reserved1 = 0, reserved2 = 1, reserved3 = 1\n
Run Code Online (Sandbox Code Playgroud)\n\n

(“reserved1、2和3”是什么以及在哪里???)

\n\n

这是服务器的 PHP 脚本(使用 XAMPP 3.2.2 启动):

\n\n
<?php\n\n//error_reporting(E_ALL);\n\nset_time_limit(0);\n\n$IP = isset($_SERVER[\'SERVER_ADDR\']) ? $_SERVER[\'SERVER_ADDR\'] : gethostbyname(gethostname());\n\necho $IP . \'\\r\\n\';\n\n$host = $IP; //$_SERVER[\'SERVER_ADDR\']; //host\n$port = 9000; //port\n$null = NULL;\n$read = NULL;\n$except = NULL;\n\nfunction send_message($msg) {\n    global $clients;\n    foreach ($clients as $changed_socket) {\n        @socket_write($changed_socket, $msg, strlen($msg));\n    }\n    return true;\n}\n\n//Unmask incoming framed message\nfunction unmask($text) {\n    $length = ord($text[1]) & 127;\n    if ($length == 126) {\n        $masks = substr($text, 4, 4);\n        $data = substr($text, 8);\n    } elseif ($length == 127) {\n        $masks = substr($text, 10, 4);\n        $data = substr($text, 14);\n    } else {\n        $masks = substr($text, 2, 4);\n        $data = substr($text, 6);\n    }\n    $text = "";\n    for ($i = 0; $i < strlen($data); ++$i) {\n        $text .= $data[$i] ^ $masks[$i % 4];\n    }\n    return $text;\n}\n\n//Encode message for transfer to client.\nfunction mask($text) {\n    $b1 = 0x80 | (0x1 & 0x0f);\n    $length = strlen($text);\n\n    if ($length <= 125)\n        $header = pack(\'CC\', $b1, $length);\n    elseif ($length > 125 && $length < 65536)\n        $header = pack(\'CCn\', $b1, 126, $length);\n    elseif ($length >= 65536)\n        $header = pack(\'CCNN\', $b1, 127, $length);\n    return $header . $text;\n}\n\n//handshake new client.\nfunction perform_handshaking($receved_header, $client_conn, $host, $port) {\n    $headers = array();\n    $lines = preg_split("/\\r\\n/", $receved_header);\n    foreach ($lines as $line) {\n        $line = chop($line);\n        if (preg_match(\'/\\A(\\S+): (.*)\\z/\', $line, $matches)) {\n            $headers[$matches[1]] = $matches[2];\n        }\n    }\n\n//var_dump($headers);\n\n    $secKey = $headers[\'Sec-WebSocket-Key\'];\n\n    $secAccept = base64_encode(pack(\'H*\', sha1($secKey . \'258EAFA5-E914-47DA-95CA-C5AB0DC85B11\')));\n//hand shaking header\n    $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\\r\\n" .\n            "Upgrade: websocket\\r\\n" .\n            "Connection: Upgrade\\r\\n" .\n            "WebSocket-Origin: $host\\r\\n" .\n            "WebSocket-Location: ws://$host:$port/socket_listener_1.php\\r\\n" .\n            "Sec-WebSocket-Accept:$secAccept\\r\\n\\r\\n";\n    socket_write($client_conn, $upgrade, strlen($upgrade));\n}\n\n$ultimotimestamp = time();\n//----------------------------------------------------------------------------------\n//Cos\xc3\xac dovrebbe ripartire il socket in caso di crash\n//Crea collegamento TCP/IP\n$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);\n\n//Se non ci si pu\xc3\xb2 connettere all\'indirizzo del socket, quindi il server \xc3\xa8 chiuso\n//riparte tutto se il server non si connette\n/* -E- */ while (@socket_connect($socket, $host, $port) === FALSE) {\n\n//Parte un nuovo server\n    echo "SOCKET SERVER STARTED\\n\\n";\n\n//Porta riutilizabile (DEFAULT SI)\n    socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);\n//Crea collegamento TCP/IP\n    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);\n\n//Lega il socket ad un indirizzo specifico\n    if (socket_bind($socket, $host, $port) !== FALSE) {\n\n//mette il socket server in ascolto\n        socket_listen($socket);\n\n//crea, e aggiunge il socket server alla lista\n        $clients = array($socket);\n\n//comincia un loop che non si ferma mai\n        while (true) {\n\n\n//la variabile changed prende la lista dei clienti (nel primo caso solo il server)\n            $changed = $clients;\n\n//La funzione socket_select() accetta un array di socket e si mette in attesa di una variazione di stato su questi. \n//Questa, derivando come background dai socket BSD, riconoscer\xc3\xa0 che questi array di risorse socket sono in realt\xc3\xa0 \n//dei set di descrittori di file. Saranno monitorati 3 set di socket.\n            socket_select($changed, $read, $except, 10, 0);\n\n//se in socket ci sono nuovi clients\n            if (in_array($socket, $changed)) {\n\n                $socket_new = socket_accept($socket); //accetta il nuovo socket (di default)\n\n                $header = socket_read($socket_new, 2048); //legge l\'header del nuovo client, al quale inviare i dati\n\n                array_push($clients, $socket_new); //aggiunge alla lista dei clients il nuovo collegamento\n\n\n                if (!empty($header)) { //Se l\'header non \xc3\xa8 vuoto\n                    perform_handshaking($header, $socket_new, $host, $port); //fa un nuovo handshake, ossia una sorta di codifica dei dati\n\n                    socket_getpeername($socket_new, $ip); //prende l\'ip dal socket connesso\n\n                    $response = mask(json_encode(array(\'type\' => \'system\', \'message\' => $ip . \' connected\'))); //prepare json data\n                    send_message($response); //notify all users about new connection\n\n                    echo $ip . " connesso\\n\\n";\n                }\n\n\n                $found_socket = array_search($socket, $changed); //cerca array socket dentro changed\n\n                unset($changed[$found_socket]); //elimina l\'indice trovato dall\'array\n            }\n\n\n            if (time() - $ultimotimestamp >= 5) {\n                $response = mask(json_encode(array(\'type\' => \'bip\', \'message\' => "1")));\n                send_message($response); //notify all users about new connection\n\n                $ultimotimestamp = time();\n            }\n\n//ciclo dei socket connessi\n            foreach ($changed as $changed_socket) {\n\n//scrive i dati del socket in un buffer di 2048 bytes\n                /* -E- */ //while (socket_recv($changed_socket, $buf, 2048, 0) > 0) {\n                while ($bytes = socket_recv($changed_socket, $buf, 2048, 0) > 1) {\n//while (!false === ($buf = socket_read($changed_socket, 2048, PHP_BINARY_READ))) {\n                    //var_dump($bytes);\n//echo \'\\n\\n\';\n\n                    $received_text = unmask($buf); //smaschera dati buffer\n                    $tst_msg = json_decode($received_text); //decodifica in json \n\n                    $response_text = mask(json_encode($tst_msg)); //lo rimaschera\n                    send_message($response_text); //invia il dato a $changed_socket, che \xc3\xa8 una risorsa socket\n\n                    echo $response_text . "\\n\\n"; //Mostra il dato inviato a schermo\n\n                    break 2; //esce fino al ciclo while (di 2 livelli sopra)\n                }\n\n//il buffer legge il socket di prima, fino a 2048 bytes\n                /* -E- */ //if (socket_recv($changed_socket, $buf, 2048, 0) === FALSE) { // se il $buf \xc3\xa8 false, quindi si presuppone che il client sia disconnesso\n\n                if ($bytes = socket_recv($changed_socket, $buf, 2048, 0) === FALSE) {\n                    var_dump($bytes);\n                    $found_socket = array_search($changed_socket, $clients);\n                    socket_getpeername($changed_socket, $ip);\n                    unset($clients[$found_socket]); // rimuove il client dall\'array dei clients\n                }\n            }\n            //sleep(0.05);\n        }\n        socket_close($socket); //in caso di errore del ciclo si chiude il socket in ascolto\n    }\n    socket_close($socket);\n}\nsocket_close($socket);\n
Run Code Online (Sandbox Code Playgroud)\n\n

服务器屏幕:\n套接字侦听器

\n\n

客户端屏幕\n操作码

\n\n

响应头

\n\n

这是来自我的客户端的 Wireshark TCP 跟踪。询问我是否需要新的屏幕截图。

\n\n

TCP 跟踪

\n\n

我没有激活防火墙和防病毒软件。你知道为什么它在我的电脑上不起作用吗?首先工作了1年。

\n\n

谢谢

\n

小智 0

根据我的经验,即使RFC6455也没有备注 RSV1,但我测试过它在 Chrome 上代表“isMasked”。