2013-03-01 2 views
1

Я совершенно новой для чистого программирования и не может решить эту проблемуPerl клиент TCP не отображает входящие данные

У меня есть сервер (какой-то LPT порт для TCP/IP прокси), который автоматически пытается установить соединение в случайном интервале. Мне нужно прослушивать определенный порт и общаться с сервером. Это клиент. Он отлично работает с Perl TCP сервером .. Но в этом случае ждет .... ничего не происходит

#!/usr/bin/perl -w 
use IO::Socket; 
my $sock = new IO::Socket::INET(
    LocalHost => '192.168.1.1', 
    LocalPort => '7000', 
    Proto  => 'tcp', 
    Listen => 1, 
    Reuse  => 1, 
); 
die "Could not create socket: $!\n" unless $sock; 
my $new_sock = $sock->accept(); 
while (<$new_sock>) { 
    print $_; 
} 
close($sock); 

Это хорошо работает с моим простым сервером TCP, но с этим «черным ящиком» - Нету На клиенте машина есть два соединения:

tcp  0  0 192.168.1.1:7000  0.0.0.0:*    LISTEN  
tcp  0  0 192.168.1.1:7000  192.168.1.2:33822  ESTABLISHED 

Но если я пытаюсь с

nc -l 192.168.1.1 7000 

Он работает как шарм, данные течет. И только одно соединение присутствует (как и второе)

tcpdump фрагмент передачи одного символа, захваченного на клиенте. Кажется OK

21:42:00.242172 IP (tos 0x0, ttl 64, id 30448, offset 0, flags [DF], proto TCP (6), length 53) 
192.168.1.2.33837 > 192.168.1.1.7000: Flags [P.], cksum 0x5646 (correct), seq 3592562130:3592562131, ack 1351632513, win 92, options [nop,nop,TS val 140364552 ecr 92554083], length 1 

Я не знаю, что я делаю неправильно ... Более сложные примеры не работают для меня, как я не знаю, как отлаживать их ...

+0

Страдает от буферизации? Что делать, если вы добавляете '$ | = 1; '? – ikegami

+0

Нет двух соединений, кстати. Только второе подключено. Существует сокет для прослушивания ('$ sock') и подключенный клиентский сокет (' $ new_sock'), что отлично. – ikegami

+0

$ | = 1; Добавлено после использования ... didn 'трюк ... сервер, отправляющий ascii chars ... должен работать ... – pugnator

ответ

2

<$new_sock>, сокращение от readline($new_sock), возвращается только после того, как получена полная линия, то есть при получении новой строки.

sysread вернется, как только данные будут доступны, поэтому вы можете использовать это.

my $rv = sysread($new_sock, my $buf, 64*1024); 

В качестве альтернативы, поскольку линии, которые вы получаете, заканчиваются возвратом каретки, вы можете сообщить об этом на Perl.

$/ = "\r"; 
+0

Большое спасибо за это решение! – pugnator

+0

Хотелось бы отметить, что это хорошая идея ограничить объем любых изменений ['$ /'] (http://perldoc.perl.org/perlvar.html#%24%2f "perldoc -v ' $/' "). –

Смежные вопросы