在C#/ Perl连接中使用Socket缓冲区溢出

时间:2012-01-31 10:33:57

标签: c# perl sockets buffer

我有一个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();

1 个答案:

答案 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来确定问题是在发件人,收件人还是介于两者之间。


sysreadread的“怪癖”:

无论请求了多少字节,

sysread都会在字节字节可用时立即返回。这意味着如果字节在调用时已经可用,它会立即返回。它将阻塞,直到数据包进入否则。这意味着如果想要一个特定数量的字符,就需要循环。

相反,read等待所请求的字节数可用。它只会在EOF或错误时返回。

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