获得响应时IO :: Socket超时

时间:2009-10-02 17:11:06

标签: perl sockets http-headers

我正在尝试使用IO :: Socket :: INET连接到Web服务(是的,我知道有很多更好的模块用于执行此操作,但我没有它们并且无法添加它们,所以请不要建议),但我已经超时(我认为这就是它在做什么)等待回复。

这是我的代码的基本关键(我之前使用所有正确的标题填充内容,并设置它等):

$httpSock->print($content);

my @lines = $httpSock->getlines();
foreach my $line ( @lines ) {
    print $line;
}

似乎我的请求是立即发出的,然后它等待大约2分钟后再吐出响应。如果我改变代码以使用原始套接字recv而不是getlines(),则ala:

$httpSock->recv($data, 1024);

我立刻得到了回复(虽然只有前1024个字符)。我在这里做错了吗?我正在使用足够晚的版本的IO :: Socket,autoflush 应默认启用,但明确启用它似乎没有任何区别。我可能也只是继续读取套接字,直到我得到整个响应,但这肯定比使用getlines()<$httpSock>更麻烦。

提前致谢。

2 个答案:

答案 0 :(得分:3)

我在使用您发布的代码段重新创建问题时遇到问题。这是我测试过的代码:

use strict;
use warnings;
use IO::Socket;

my $httpSock = new IO::Socket::INET(
    PeerAddr => 'www.google.com',
    PeerPort => '80',
    Proto    => 'tcp',
);

my $content = "HEAD / HTTP/1.0\r\nHost: www.google.com\r\n\r\n";

$httpSock->print($content);
my @lines = $httpSock->getlines();
foreach my $line (@lines) {
    print $line;
}

结果如下:

$ time ./1.pl
HTTP/1.0 200 OK
-snip-  

real    0m0.084s
user    0m0.025s
sys 0m0.007s

答案 1 :(得分:3)

问题是getlines()会一直等到连接关闭。如果您要连接的Web服务未关闭连接,则getlines函数将等待,并认为有更多数据正在进行中。当您的连接在2分钟左右之后超时时,getlines会看到连接关闭,并将收到的行返回给您。另一方面,Recv将获取当前连接上的预定限制并将其返回到您立即处理的缓冲区,但是如果当前没有数据,它将等待它获得一些数据。我知道你认为它很混乱,但这可能对你有用:

$httpSock->recv($buf, 1024);
$message = "";
while (length($buf) > 0) {
    $message .= $buf;
    $httpSock->recv($buf, 1024, MSG_DONTWAIT);
}
print $message;

如果连接为空,MSG_DONTWAIT将导致recv不等待消息。您还可以将1024增加到某个大数字以减少循环次数,甚至可能立即获得整个消息。

这也应该让你保持套接字打开以供进一步使用,直到你自己关闭它。

我想知道google示例是否有效,因为google.com在响应后正在关闭连接。