Perl 多次接收HTTP数据
我正在编写一个自定义HTTP服务器来为我自己的JavaScript应用程序提供服务 使用此代码从浏览器获取标题非常简单Perl 多次接收HTTP数据,perl,sockets,Perl,Sockets,我正在编写一个自定义HTTP服务器来为我自己的JavaScript应用程序提供服务 使用此代码从浏览器获取标题非常简单 $data_length = 0; $client_data = ""; while ( <$client_socket> ) { if ( /Content-Length: (\d+)/ ) { $data_length = $1; } $client_data .= $_; last if ( $_ =~ /
$data_length = 0;
$client_data = "";
while ( <$client_socket> ) {
if ( /Content-Length: (\d+)/ ) {
$data_length = $1;
}
$client_data .= $_;
last if ( $_ =~ /^\s*$/ ); # end of headers
}
# Receiving the body-entity (POST data) is where things start getting unpleasant.
$bytes_read = 0;
$bytes_total = 0;
{
use bytes;
$client_data_body = "";
$bytes_to_read = $data_length;
$count_recieve = 0;
while ( $bytes_to_read > 0 ) {
print "Bytes to read: $bytes_to_read\n";
$client_socket->recv( $client_data_body, $bytes_to_read );
$bytes_read = length $client_data_body;
$bytes_total += $bytes_read;
$bytes_to_read = $bytes_to_read - $bytes_read;
$client_data .= $client_data_body;
}
}
此时,脚本将永远等待。如果我在浏览器中单击“停止”,我将获得无限多的字节来读取:7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
Bytes to read: 7687
当然,有时数字会与这些不同,除了最后一个数字,它似乎停留在7100和7800之间
非常非常少的情况下,脚本不会挂起,并且会按照我希望的方式完成它的工作首先,永远不要使用
使用字节代码>。任何一种使用它的方式都有其固有的缺陷。幸好它在这里什么也没做。把它拿走
至于你没完没了的呼叫recv
,那是因为你没有检查EOF或错误。下面是实现所需功能的代码:
my $body = '';
while ($bytes_to_read) {
my $rv = sysread($client_socket, $body, $bytes_to_read, length($body));
die("Read failed: $!") if !defined($rv);
die("Read failed: Premature EOF") if !$rv;
$bytes_to_read -= $rv;
}
我从recv
切换到sysread
,因为它对于像TCP这样的流协议更有意义
所有这些都是你想要的
my $body;
if ($request_method eq 'POST') {
$body = '';
if (defined($body_length)) {
# Content-Length provided.
my $bytes_to_read = $body_length;
while ($bytes_to_read) {
my $rv = sysread($client_socket, $body, $bytes_to_read, length($body));
die("Read failed: $!") if !defined($rv);
die("Read failed: Premature EOF") if !$rv;
$bytes_to_read -= $rv;
}
} else {
# Content-Length not provided.
while (1) {
my $rv = sysread($client_socket, $body, 64*1024, length($body));
die("Read failed: $!") if !defined($rv);
last if !$rv;
}
}
}
我刚试过你的密码。它在第二次迭代时仍然挂起。当我单击“停止”时,所有剩余的数据都被接收到。如果数据挂起,这意味着到达的字节数少于$body\u length
字节。我必须调用shutdown($client\u socket,1);在从插座读取之前。现在,它的工作原理就像一个charmNonsense。如果您这样做,您将无法发送响应。
my $body;
if ($request_method eq 'POST') {
$body = '';
if (defined($body_length)) {
# Content-Length provided.
my $bytes_to_read = $body_length;
while ($bytes_to_read) {
my $rv = sysread($client_socket, $body, $bytes_to_read, length($body));
die("Read failed: $!") if !defined($rv);
die("Read failed: Premature EOF") if !$rv;
$bytes_to_read -= $rv;
}
} else {
# Content-Length not provided.
while (1) {
my $rv = sysread($client_socket, $body, 64*1024, length($body));
die("Read failed: $!") if !defined($rv);
last if !$rv;
}
}
}