C#/ Perl连接中的套接字缓冲区溢出

我有一个TCP Socket beetwen两个程序,一个C#服务器和一个Perl客户端.客户端应该从服务器接收XML流. XML文件(由C#程序生成)大约为437KB,但是无论缓冲区有多大,客户端都只会收到408KB.在客户端,我使用IO :: Socket :: INET,而服务器端使用TcpListener和TcpClient的组合.如何在客户端正确定义缓冲区?现在我正在使用该代码:

# PERL CLIENT
my $socket = new IO::Socket::INET (
    PeerHost => '192.168.*.*',
    PeerPort => '*****',
    Proto => 'tcp'
) or die "Error while creating Socket";
#
# OTHER STUFFS...
#
my $buffer = 500000000; # IT DOESNT SEEM TO USE THAT VALUE AT ALL
$socket->recv($xmlbody, $buffer);


// C# SERVER
// OTHER STUFFS...
byte[] result = encoding.GetBytes(xml);
clientStream.Write(result, 0, result.Length);
clientStream.Flush();
clientStream.Close();
tcpClient.Close();

解决方法:

我从不使用recv,所以我不知道它的怪癖.我使用sysread.

sub read_until_eof {
   my ($fh) = @_;
   my $buf = '';
   for (;;) {
      my $rv = sysread($fh, $buf, 64*1024, length($buf))
      die $! if !defined($rv);
      return $buf if !$rv;
   }
}

如果这样做不能解决问题,建议您使用tcpdump确定问题是出在发送方,接收方还是两者之间.

sysread和read的“怪癖”:

sysread总是在字节字节可用时立即返回,无论请求了多少字节.这意味着如果调用时字节已经可用,它将立即返回.它将阻塞直到有其他数据包进入.这意味着如果需要特定数量的字符,则需要循环.

相反,读取将等待直到请求的字节数可用为止.然后仅在EOF或错误时返回.

read和sysread实际上在字符级别上工作,这意味着您实际上指定了所需的字符数,而不是字节数.这些字符可以是字节,Unicode代码点或其他内容,具体取决于您添加到句柄的IO层.

上一篇:openssl安装


下一篇:与PHPExcel一样,perl Spreadsheet :: WriteExcel是否更快且占用的内存更少?