我有一个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();
答案 0 :(得分:4)
我从不使用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
都会在字节字节可用时立即返回。这意味着如果字节在调用时已经可用,它会立即返回。它将阻塞,直到数据包进入否则。这意味着如果想要一个特定数量的字符,就需要循环。
相反,read
等待所请求的字节数可用。它只会在EOF或错误时返回。
read
和sysread
实际上在字符级别工作,这意味着您实际指定了所需的字符数,而不是字节数。这些字符可以是字节,Unicode代码点或其他任何字符,具体取决于您添加到句柄的IO层。