超简单的HTTP套接字服务器,用PHP编写,performance出意外

tldr;

  1. PHP非常小的stream套接字服务器
  2. 行为很奇怪,因为有时它成功地服务HTTP请求, 有时在同一个进程内失败
  3. 在不同的浏览器中performance奇怪 – 几乎每次在Chrome都失败,从来没有在IE11

码:

 $server = stream_socket_server("tcp://0.0.0.0:4444", $errno, $errorMessage); if ($server === false) throw new UnexpectedValueException("Could not bind to socket: $errorMessage"); $e = "\r\n"; $headers = array( "HTTP/1.1 200 OK", "Date: " . date('D') . ', ' . date('m') . ' ' . date('M') . ' ' . date('Y') . ' ' . date('H:i:s') . ' GMT' , 'Server: MySpeedy', 'Connection: close', 'Content-Type: text/plain', 'Content-Length: 2' ); $headers = implode($e, $headers) . $e . $e .'ok'; for (;;) { $client = stream_socket_accept($server); if ($client) { echo 'Connection accepted from '.stream_socket_get_name($client, false) . $e; fwrite($client, $headers); fclose($client); } } 

给我这个http响应(telnet结果):

 HTTP/1.1 200 OK Date: Fri, 11 Nov 2015 20:09:02 GMT Server: MySpeedy Connection: close Content-Type: text/plain Content-Length: 2 ok 

这导致我得到这些结果:

  • Chrome中的ERR_CONNECTION_RESET几乎每次都可以(20-30个请求中的1个可以得到预期的响应)
  • Firefox中The connection was reset ,2-3次请求中大约有1次
  • 正确的,每次在Internet Explorer 11的预期响应(耶,IE是最好的东西)。

我究竟做错了什么? 它是由HTTP头 (我不能说,如果我已经格式化他们不正确)或套接字循环或..?

您不会从客户端读取HTTP请求,而只需发送您的响应并关闭连接。 但是在仍然有数据要读取时关闭套接字将导致连接重置发送回客户端,这就是您将在Chrome中使用ERR_CONNECTION_RESET所看到的内容。 其他浏览器的行为可能会有所不同,如果浏览器在处理重置之前可以显示响应,也是一个计时问题。

在关闭套接字之前,先解决它,先读取客户端的完整请求。