【问题标题】:PHP: Connection: keep-alive problem reading socket dataPHP:连接:读取套接字数据的保持活动问题
【发布时间】:2010-03-06 08:56:11
【问题描述】:

尝试将数据写入套接字并读取响应。

$packet = "GET /get-database HTTP/1.1\r\n";
$packet .= "Host: 192.168.3.136:3689\r\n";
//$packet .= "Accept-Encoding: gzip\r\n";
$packet .= "Viewer-Only-Client: 1\r\n";
$packet .= "Connection: keep-alive\r\n\r\n";

socket_write($socket, $packet, strlen($packet));

do{
    $buf = "";
    $buf = socket_read($socket, 4096);
    $data .= $buf;
}while($buf != "");

echo "$data\r\n\r\n";

如果我将连接设置为close,那么它可以工作并且我能够读取响应。问题是,在我读取数据后,我需要写回套接字。响应包含我需要发回以进行验证的 id。如果我在两个单独的套接字上写入服务器,它会拒绝验证回帖。所以我只能假设,我需要在相同的“打开连接”或“会话”上发布。

有什么想法吗?

我想弄清楚为什么我无法使用Connection: keep-alive 从套接字读取数据

####### 编辑

这方面已经有了一些发展。 我试图让这变得非常简单,以便我可以查明问题:

现在我的代码如下所示:

$fp = pfsockopen("192.168.3.136", "3689");
$content = "GET /login?id=a90347 HTTP/1.1\r\n";
$content .= "Connection: keep-alive\r\n\r\n";

fputs($fp, $content);

while (!feof($fp)) {
    echo fgets($fp, 8192);
}

发生的情况是,当我执行 fputs 时,我会从服务器获得一个如下所示的响应标头:

HTTP/1.1 200 OK
Date: Fri, 05 Mar 2010 22:05:47 GMT
RIPT-Server: iTunesLib/3.0.2 (Mac OS X)
Content-Type: application/x-dmap-tagged
Content-Length: 32

然后我的光标就停在那里。在 15 秒到一分钟后,我有时会得到内容,但我仍然卡在 while 循环中。

有谁知道,如果在服务器发送了响应标头之后,我是否应该向它发送一些东西以让它知道我已经为内容做好了准备?

同样,我不认为是这种情况,因为当我查看网络上的数据包时,我可以看到整个响应。那和我有时会得到响应内容的事实。真的是 PHP 无法处理这个问题,或者我离基地太远了。

仍然需要帮助..... :(

工作代码
$fp = pfsockopen("192.168.3.136", "3689");
$header = "GET /login?id=5648349 HTTP/1.1\r\n";
$header .= "Connection: keep-alive\r\n\r\n";

fputs($fp, $header);

$headers = array();

while(true){
    $line = fgets($fp, 8192);
    if($line == "\r\n"){ break; }
    $line_parts = explode(': ',$line);
    echo $line_parts[1]."\r\n";
  $headers[$line_parts[0]] = $line_parts[1];
}
$content = fread($fp,intval($headers['Content-Length']));
echo $content;

现在,我必须对“\r\n”测试保持警惕,因为我确信某些响应可能只在标头之后发送一个“\n”。

【问题讨论】:

  • 您确定连接仍然有效吗?即使使用“连接:保持活动”?
  • 据我所知。我不知道连接什么时候会死,因为它挂在“socket_read”上。
  • 如果您的描述准确,那么远程系统没有实现 HTTP - 这是无状态的。
  • "symcbean",这就是我觉得它是 PHP 的地方。因为如果我打开 Wireshark 并观察网络上的数据包,我可以看到我的数据包从哪里发出,远程系统会回复我的计算机。所以它正确处理请求。我的脚本只是没有读回响应。同样,如果我使用 Connection: close,它会读回响应,但会关闭连接。

标签: php sockets


【解决方案1】:

您是否尝试将套接字设置为非阻塞模式?

socket_set_nonblock($socket);

EDIT1:好的。只是预感...试试这个...

$fp = pfsockopen("192.168.3.136", "3689");
$content = "GET /login?id=a90347 HTTP/1.1\r\n";
$content .= "Connection: keep-alive\r\n\r\n";

fputs($fp, $content);

$headers = array();

do
{
  $line = fgets($fp, 8192);
  $line_parts = ecplode(': ',$line);
  $headers[$line_parts[0]] = $line_parts[1];
} while($line != '');

$content = fread($fp,intval($headers['Content-Length']));

echo $content;

【讨论】:

  • 我确实尝试过,但这似乎并不是问题所在,因为在收到初始回复之前我不需要做任何事情。已经有了更多的发展:) 仍然坚持这一点。我不知道如何在评论中发布代码,因为它似乎总是聚集在一起,所以我要编辑我的问题。
  • @Senica:我只是在猜测非阻塞......但我知道在问题中发布代码是去那里的正确方法。
  • 太棒了!只好稍微修改一下。但你是对的,fgets 没有读取内容。
  • 我很高兴这对你有用。如果您尝试阅读的内容多于可用内容,PHP 将阻止等待更多内容。
猜你喜欢
  • 2012-11-12
  • 2020-01-12
  • 2018-04-13
  • 2020-12-20
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
相关资源
最近更新 更多