我正在编写一个自定义HTTP服务器来为我自己的JavaScript应用程序提供服务。
使用此代码
,从浏览器中获取标题非常简单$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;
}
}
在一些迭代之后,上面的代码几乎总是在recv()
处挂起。 sysread()
的行为方式相同。
这是上述脚本的实际输出
Bytes to read: 48821
Bytes to read: 35168
Bytes to read: 24245
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
Bytes to read: 7687
Bytes to read: 7687
当然有时这些数字会与这些不同,除了最后一个,它似乎停留在7100和7800之间。
很少,脚本不会挂起,并按照我想要的方式完成它的工作
答案 0 :(得分:2)
首先,永远不要使用use bytes;
。任何使用它本身就是马车。这件好事实际上没有做任何事情。删除它!
至于你无休止的电话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;
}
}
}