Переполнение буфером Socket в соединении C # / Perl - PullRequest
3 голосов
/ 31 января 2012

У меня есть сокет TCP между двумя программами, сервером C # и клиентом Perl.Предполагается, что клиент получает поток XML с сервера.Файл XML (сгенерированный программой C #) имеет размер около 437 КБ, но клиент получает только 408 КБ, независимо от размера буфера.На стороне клиента я использую 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 Ответ

4 голосов
/ 31 января 2012

Я никогда не использую 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 или любым другим, в зависимости от того, какой слой ввода-вывода вы добавили в дескриптор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...