LINUX.ORG.RU

troubles with perl & tcp sockets


0

0

HI ALL.

tcp server

#!/usr/bin/perl
use Socket;
$port = '7025';
$proto = getprotobyname('tcp');

$EOL = "\015\012";
socket(SERV, PF_INET, SOCK_STREAM, $proto) or die "socket: $!\n";
setsockopt(SERV, SOL_SOCKET, SO_REUSEADDR, pack("l",1)) or die "setsock $!\n";

$paddr = sockaddr_in($port,INADDR_ANY);
bind(SERV,$paddr) or die "bind: $! \n";
listen(SERV, SOMAXCONN) or die "listen: $! \n";
print "Server started on port $port\n";

while ($client_addr = accept (CLIENT,SERV)) {
($client_port, $client_ip ) = sockaddr_in($client_addr);
$client_ipnum = inet_ntoa($client_ip);
$client_host = gethostbyaddr($client_IP , AF_INET);
print "connection from $client_host $client_ipnum \n";
while ( ) {
if (/date|time/i) {print CLIENT `date 2>&1`; print CLIENT $EOL;}
elsif (/quit|exit/i) {last; }
elsif (/who/i ) {$out = `who` ; print CLIENT $out , $EOL;}
else {print CLIENT "Commands: quit date who " ,$EOL};
}
close CLIENT;
}

tcp client или telnet большой разницы нет.

#!/usr/bin/perl

use Socket;
use IO::Handle;

$host = "127.0.0.1";
$port = "7025";
$EOL = "\015\012";

socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
connect (SOCK, $paddr);
SOCK->autoflush(1);
print SOCK "who" ,$EOL;
#print SOCK "date" ,$EOL;

while () {print $_;}
close SOCK;
exit;

если я коннекчусь telnet-ом на сервер и набираю команду например who то команда выполняется ,
но ее вывод не видно , если я наберу другую команду например date , то теперь мне выведет
вывод предидущей команды и т.д . тоже самое с клиентом на perl . где тут собака поралась ???
в чем может быть дело ?


telnet 127.0.0.1 7025
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
who
who
sasha pts/0 Jan 6 08:54 (192.168.1.2)
sasha pts/1 Jan 6 08:54 (192.168.1.2)
sasha pts/2 Jan 6 09:01 (192.168.1.2)
sasha pts/3 Jan 6 09:02 (192.168.1.2)
sasha pts/4 Jan 6 09:40 (192.168.1.2)

date
sasha pts/0 Jan 6 08:54 (192.168.1.2)
sasha pts/1 Jan 6 08:54 (192.168.1.2)
sasha pts/2 Jan 6 09:01 (192.168.1.2)
sasha pts/3 Jan 6 09:02 (192.168.1.2)
sasha pts/4 Jan 6 09:40 (192.168.1.2)

who
Tue Mar 28 10:55:19 GMT-4 2006

i t.d.

★★


Врешь ты, мил человек :-(
Твой "сервер" вообще работать не может - ты же ничего от клиента
не читаешь!

И где, черт возьми, use warnings (или -w) и use strict? Где они?
Если бы они были, perl бы тебе сказал, что у тебя на одной строке
$client_ip а на другой $client_IP (опечаточка?).

Да, и используй пожалуйста не use Socket а use IO::Socket::INET -
очень упрощает все дело (читай perldoc IO::Socket::INET).

Короче если хочешь помощь - запости _реальный_ код, с use warnings
и use strict.

HTH

Onanim
()

Ну ладно, вот тебе вариант:

#!/usr/bin/perl -w

use strict;
use IO::Socket::INET;

my $EOL = "\015\012";

my $listener = IO::Socket::INET->new( LocalAddr => 'localhost',
                                      LocalPort => 7025,
                                      ReuseAddr => 1,
                                      Listen    => 5 );

$listener or die "cannot create listener: $!\n";

while(1)
{
    my $client = $listener->accept  or die "accept: $!\n";
    $client->autoflush(1);
    print 'Got connection from ', $client->peerhost, ' ', $client->peerport, "\n";
    while (<$client>)
    {
        /quit/i      and  last;
        /who|date/i  and  do { $client->print(`$_`, $EOL); next };
        $client->print('commands: who date quit', $EOL);
    }
    print "Disconnected\n";
}

Onanim
()
Ответ на: комментарий от Onanim

>
>Врешь ты, мил человек :-(
>Твой "сервер" вообще работать не может - ты же ничего от клиента
>не читаешь!

>И где, черт возьми, use warnings (или -w) и use strict? Где они?
>Если бы они были, perl бы тебе сказал, что у тебя на одной строке
>$client_ip а на другой $client_IP (опечаточка?).

>Да, и используй пожалуйста не use Socket а use IO::Socket::INET -
>очень упрощает все дело (читай perldoc IO::Socket::INET).

>Короче если хочешь помощь - запости _реальный_ код, с use warnings
>и use strict.

не надо быть таким категоричным , в данном случае эти строчки
$client_ipnum = inet_ntoa($client_ip);
$client_host = gethostbyaddr($client_IP , AF_INET);
print "connection from $client_host $client_ipnum \n";
вообше роли не играют .

в чем проблема всетаки ? IO::Socket не хочу исрользовать .

насчет -w проблема не в синтаксисе , а в логике IMHO , так что perl -w мне тут не поможет

j262 ★★
() автор топика
Ответ на: комментарий от j262

вот сцука а
пока постил , <CLIENT> пропало .

troubles with perl & tcp sockets
HI ALL.

tcp server

#!/usr/bin/perl
use Socket;
$port = '7025';
$proto = getprotobyname('tcp');

$EOL = "\015\012";
socket(SERV, PF_INET, SOCK_STREAM, $proto) or die "socket: $!\n";
setsockopt(SERV, SOL_SOCKET, SO_REUSEADDR, pack("l",1)) or die "setsock $!\n";

$paddr = sockaddr_in($port,INADDR_ANY);
bind(SERV,$paddr) or die "bind: $! \n";
listen(SERV, SOMAXCONN) or die "listen: $! \n";
print "Server started on port $port\n";

while ($client_addr = accept (CLIENT,SERV)) {
($client_port, $client_ip ) = sockaddr_in($client_addr);
$client_ipnum = inet_ntoa($client_ip);
$client_host = gethostbyaddr($client_IP , AF_INET);
print "connection from $client_host $client_ipnum \n";
while (<CLIENT>) {
if (/date|time/i) {print CLIENT `date 2>&1`; print CLIENT $EOL;}
elsif (/quit|exit/i) {last; }
elsif (/who/i ) {$out = `who` ; print CLIENT $out , $EOL;}
else {print CLIENT "Commands: quit date who " ,$EOL};
}
close CLIENT;
}

tcp client или telnet большой разницы нет.

#!/usr/bin/perl

use Socket;
use IO::Handle;

$host = "127.0.0.1";
$port = "7025";
$EOL = "\015\012";

socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
connect (SOCK, $paddr);
SOCK->autoflush(1);
print SOCK "who" ,$EOL;
#print SOCK "date" ,$EOL;

while () {print $_;}
close SOCK;
exit;

если я коннекчусь telnet-ом на сервер и набираю команду например who то команда выполняется ,
но ее вывод не видно , если я наберу другую команду например date , то теперь мне выведет
вывод предидущей команды и т.д . тоже самое с клиентом на perl . где тут собака поралась ???
в чем может быть дело ?

j262 ★★
() автор топика
Ответ на: комментарий от j262

> в чем проблема всетаки ? IO::Socket не хочу исрользовать .

"Мальчик, ты тормоз?" (C)

Я ж тебе русским языком написал - твой "сервер" не читает
данные от клиента!
Что в твоем коде делает конструкция while() ? А? Не слышу?
Может там подразумевалось что-то типа while(<CLIENT>) ?
Еще раз - твой код (который ты запостил) просто не может работать
так, как ты описал. Запости свой _реальный_ код, на котором
проявляется тот симптом, который ты описал.
Да, и если там не будет use strict и use warnings - никаких советов
ты от меня не дождешься.
BTW в perldoc perlipc есть примеры, пофтыкай на них ;-)

HTH

P.S. А чем тебе IO::Socket::INET не угодил? Он входит в стандартный
Perl distribution уже с хрен знает какого времени.


Onanim
()
Ответ на: комментарий от j262

> вот сцука а
> пока постил , <CLIENT> пропало .
>

О! Это ты уже поправил - молоцца! ;-)
Осталось обучиться use strict и use warnings ;-)

Onanim
()

набери команду perldoc perlipc там есть как клиент так и сервер, как раз который и выдает в клиента команду who.

только ман большой, посередине гдето это.

vilfred ☆☆
()
Ответ на: комментарий от j262


Включи autoflush для CLIENT, для этого перед своим while(<CLIENT>)
напиши:
select((select(CLIENT), $| = 1)[0]);
(подробности в perldoc -q flush)

И поверь моему опыту - _всегда_ включай use strict и use warnings.

HTH

Onanim
()
Ответ на: комментарий от Onanim

2 vilfred tnx , я знаю этот код , там выводится текст после close CLIENT . так у меня тоже работает .

2 Onanim , если хочешь помочь , то убери издевательскии тон .
autoflush vkluchen

>Да, и если там не будет use strict и use warnings - никаких советов
>ты от меня не дождешься.
хочется сказать идинах , но как вежливый человек , спасибо не надо ваших советов.

j262 ★★
() автор топика
Ответ на: комментарий от j262

> 2 Onanim , если хочешь помочь , то убери издевательскии тон .
> autoflush vkluchen
>

А как с тобой еще разговаривать?
У тебя "autoflush vkluchen" в клиенте. Не в сервере.

Твой симптом у меня воспроизводится и исчезает после
установки autoflush в сервере, я это уже написал вверху,
для особо одаренных повторяю еще раз:

> Включи autoflush для CLIENT, для этого перед своим while(<CLIENT>)
> напиши:
> select((select(CLIENT), $| = 1)[0]);
> (подробности в perldoc -q flush)

(к серверу я подключаюсь telnet'ом)

Onanim
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.