使用socket

时间:2017-11-14 16:49:48

标签: php sockets websocket port

我有下面的代码接受使用套接字连接并显示它,然后发回几个标题,但是我看不到已经发送给监听器的正文内容,我只得到代码下面指示的标题,内容长度清楚地表明内容已发送,请帮助

    $host = "192.168.8.121";
    $port = 454;

    // don't timeout!
    set_time_limit(0);

    // create socket
    $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
    $result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
    $result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

    do {
       $spawn = socket_accept($socket) or die("Could not accept incoming connection\n");

    // read client input
       $input = socket_read($spawn, 1024) or die("Could not read input\n");

       $inputJSON = file_get_contents('php://input');
       $body = json_decode($inputJSON, TRUE); 
       print_r($input);
       print_r($body);
       print_r($inputJSON);

    // set inital headers
       $headers = [];
       $headers['Date'] = gmdate('D, d M Y H:i:s T');
       $headers['Content-Type'] = 'text/html; charset=utf-8';
       $headers['Server'] = $_SERVER['SERVER_NAME'];

       $lines = [];
       $lines[] = "HTTP/1.1 200 OK";

       // add the headers
       foreach ($headers as $key => $value) {
           $lines[] = $key . ": " . $value;
       }

       socket_write($spawn, implode("\r\n", $lines) . "\r\n\r\n" . $body) or die("Could not write output\n");
       socket_close($spawn);
    } while (true);

    // close sockets
    socket_close($socket);

我尝试了不同的方法来打印内容,但我只能打印出标题,这是我在打印$ input变量时得到的结果

     POST /test HTTP/1.1 Accept: application/json, application/xml, 
     text/json, text/x-json, text/javascript, text/xml User-Agent: 
     RestSharp/105.2.3.0 Content-Type: application/json Host: 
     192.168.8.102:454 Content-Length: 779 Accept-Encoding: gzip, 
     deflate

1 个答案:

答案 0 :(得分:0)

TCP以数据包形式发送数据并将其重新组合回流中。这意味着虽然您可以逐字节读取数据而无需关注到达接收器的数据包的正确顺序,但仍然可能发生一次调用socket_read()仅返回一个IP数据包的内容。发送方可能将标头作为一个数据包发送,然后在一个或多个其他数据包中发送内容。

通常做的是在类似于此的循环中调用receive函数:

$readTotal = 0;
while ($readTotal < $toRead) {
  $read = socket_read(...);
  if ($read === FALSE) {
    // error, cancel operation
  }
  $readTotal += $read;
}

在您的情况下,您必须从Content-Length字段中提取要读取的数量,如果您无法读取标头中承诺的字节数,则可能会在循环中设置超时。