用PHP编写的超简单HTTP套接字服务器,行为出乎意料 [英] Ultra simple HTTP socket server, written in PHP, behaving unexpectedly

查看:28
本文介绍了用PHP编写的超简单HTTP套接字服务器,行为出乎意料的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tldr;

  1. PHP
  2. 中非常小的流套接字服务器
  3. 行为很奇怪,因为有时它会成功处理 HTTP 请求,而有时会在同一进程中失败
  4. 在不同的浏览器中表现很奇怪 - 几乎每次在 Chrome 中都失败,而在 IE11 中从不失败
  1. very minimal stream socket server in PHP
  2. acts strange since sometimes it successfully serves HTTP request and sometimes fails within the very same process
  3. acts strange across different browsers - almost every time fails in Chrome and never in 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 结果):

gives me this http response (telnet results):

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

这让我得到了这些结果:

And that leads me to these results:

  • ERR_CONNECTION_RESET 在 Chrome 中,几乎每次(可能是 20-30 中的 1 个)请求得到预期的响应)
  • 连接已重置 在 Firefox 中,大约为 2-3 中的 1请求
  • 每次都在 Internet Explorer 11 中得到正确的预期响应(是的,IE 在某些方面是最好的).
  • ERR_CONNECTION_RESET in Chrome, almost every time (maybe 1 in 20-30 requests get expected response)
  • The connection was reset in Firefox, approximately 1 in 2-3 requests
  • Correct, expected response in Internet Explorer 11 every time (yay, IE is the best in something).

我做错了什么?是否取决于 http 标头(我不能说我的格式是否错误)或 socket 循环 或...?

What am I doing wrong? Is it up to http headers (I couldn't say if I've formatted them incorrectly) or socket loop or..?

推荐答案

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

You don't read the HTTP request from the client but instead simply send your response and close the connection. But closing the socket while there are still data to read will cause a connection reset send back to the client and that's what you will see in Chrome with ERR_CONNECTION_RESET. Other browsers might behave differently and it is also a timing issue if the browser can display the response before handling the reset.

要修复它,请在关闭套接字之前先读取来自客户端的完整请求.

To fix it first read the full request from the client before you close the socket.

这篇关于用PHP编写的超简单HTTP套接字服务器,行为出乎意料的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆