Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > IO::Socket::INET не получаю ответ


Автор: alezzz 27.12.2010, 19:25
Делаю по книжке и примерам в интернете, такой вот код:
Код

#!/usr/bin/perl

use IO::Socket;
use strict;

my $socket = IO::Socket::INET->new(PeerAddr => "192.168.0.1",
                                   PeerPort => "telnet",
                                   Proto => "tcp",
                                   Type => SOCK_STREAM
                                  ) or die "Could't connect  : $@\n";
                               
$| = 1;

print "Connected...\n";
print $socket "\n\n";

print while(<$socket>);

close $socket;

На 192.168.0.1 вижу ESTABLISHED к 23 порту, но программа виснет на print while(<$socket>); (в любой комбинации, пробовал и переменной присваивать <$socket>), а я рассчитывал на что-то типа "login: " на выходе. Нигде на просторах интернета пока не нашел подобной проблемы.

ActivePerl на Windows, удаленый хост -- FreeBSD.

Автор: Pfailed 27.12.2010, 20:02
Что если перед началом чтения из сокета вставить нижеследующий код?
Код

$/ = "\012";


Автор: alezzz 27.12.2010, 20:02
попробовал тоже-самое сделать через use Socket, результат такой-же.

Цитата(Pfailed @  27.12.2010,  20:02 Найти цитируемый пост)
Что если перед началом чтения из сокета вставить нижеследующий код?

тоже-самое, виснет.

Автор: Pfailed 27.12.2010, 20:13
Тогда попробуйте читать из сокета с помощью sysread()

Автор: alezzz 27.12.2010, 21:03
Пробовал таким способом:
Код

my $byte;
while (sysread(REMOTE, $byte, 1) == 1) 
{
  print STDOUT $byte;
}

на выходе 8-10 символов "мусора". 

Попробовал запустить на FreeBSD -- результат такой-же.

Сам telnet-сервер нормально работает.

Автор: Pfailed 27.12.2010, 21:20
Видимо в этих восьми байтах приходит одна из telnet команд. Ознакомьтесь со спецификацией протокола telnet.
Помимо этого можно попробовать использовать готовое решение, есть Net::Telnet

Автор: alezzz 27.12.2010, 21:33
Про Net::Telnet я знаю, с ним все нормально работает, дело не в самом телнете а именно в сокете, телнет как простой пример.

Попробовал на http, отправил на 80 порт GET ... и получил результат обычным текстом, видимо все-таки придется ознакомиться со спецификацией telnet.

Автор: srl 20.1.2011, 23:37
Может просто в сокете нет ничего, и оно блокируется?
Попробуй неблокирующее чтение (сегодня я всем советую неблокирующее чтение, да  smile ).

Автор: alezzz 21.1.2011, 08:48
Спасибо, уже разобрался fork-ом.

А вообще, не в стране советов живем, можно и примером поделится. smile

Автор: srl 21.1.2011, 21:41
Цитата(alezzz @ 21.1.2011,  08:48)
Спасибо, уже разобрался fork-ом.

А вообще, не в стране советов живем, можно и примером поделится. smile

Угу, у нас страна примеров... 8)) У-у, демон.  smile  Ну держи:

Код

#!/usr/bin/perl

use strict;
use IO::Socket;
use IO::Select;

my $socket = IO::Socket::INET->new(
    PeerAddr => "192.168.1.1",
    PeerPort => 80,
    Proto => "tcp",
    Type => SOCK_STREAM
) or die "Could't connect: $@\n";
                               
print "Connected...\n";

my $s = IO::Select->new();
$s->add($socket);
$s->add(\*STDIN);

LOOP: while(my @handles = $s->can_read){
    foreach my $handle (@handles){
     if ($handle == \*STDIN){
         # если прочитали из STDIN - отправим это дело в наш сокет.
         my $command = <$handle>;
         print $socket $command;
     } else {
         my $str = <$handle>;
         if (!defined $str){
             # если прочитали undef из готового хендлера - значит он закрылся.
             print "Server has closed connection.\n"; 
             $s->remove($handle);
             last LOOP; # т.к. у нас всего два хендлера, то закругляемся. 
         }
         print $str;
     } # if handle
    } # foreach handle
} # while

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)