Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 多次接收HTTP数据_Perl_Sockets - Fatal编程技术网

Perl 多次接收HTTP数据

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 ( $_ =~ /

我正在编写一个自定义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;

    }

}
此时,脚本将永远等待。如果我在浏览器中单击“停止”,我将获得无限多的
字节来读取: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;
      }
   }
}