Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> помгите найти проблему в udp IO:Socket 
V
    Опции темы
gers
Дата 20.1.2008, 03:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



Здравствуйте Уважаемые коллеги!
вот есть код сервер-клиента:

Код

#!/usr/bin/perl -w

# udpqotd - сервер сообщений UDP
use strict;
use IO::Socket;

my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO, $call, $ipaddr );
$MAXLEN = 1024;
$PORTNO = 1234;
#$LAddr = inet_aton("192.168.2.1");
$sock = IO::Socket::INET->new(LocalAddr => '192.168.2.1', LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@";
$call= IO::Socket::INET->new(PeerPort=>$PORTNO, Proto=>'udp', PeerAddr =>$hishost ) or die "socket: $@";

  print "Awaiting UDP messages on port $PORTNO\n";
  $oldmsg = "This is the starting message.";
  while ($sock->recv($newmsg, $MAXLEN)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
      $hishost = gethostbyaddr($ipaddr, AF_INET);
      
        print "Client $hishost said  ''$newmsg''\n";
      $call->send($newmsg);
        #$oldmsg = "[192.168.2.3] $newmsg";
        }
        die "recv: $!";

написал второй такойже клиент-сервер на delphi, и проблема в чем:
этот сервер должен ответить в клиентскую прогу на delphi только вываливается после того как не может определить адрес для обратного ответа:
Код

Awaiting UDP messages on port 1234
Use of uninitialized value in concatenation (.) or string at ./udp.pl line 20.
Client  said  ''test''
send: Cannot determine peer address at ./udp.pl line 21


при явной подстановке айпи: 
Код

$call= IO::Socket::INET->new(PeerPort=>$PORTNO, Proto=>'udp', PeerAddr =>'192168.2.3' ) or die "socket: $@";

все работает. в чем может быть дело?


Это сообщение отредактировал(а) gers - 20.1.2008, 03:46
PM MAIL   Вверх
nitr
Дата 20.1.2008, 03:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



На сколько вижу, вы удалили некоторые строки из своего скрипта. Можете показать код, так чтобы оно соответствовал тому что в вашем "редакторе". Поясню, указана ошибка в строке 19 и 20, из приведенного  - не понятно.
Может вы тестируете на одном ПК, и просто порт занят? Если я прав, то немного измените ваш скрипт, а так получается, что скрипт "не может понять клиент или сервер". Могу ошибаться, но похоже на это.

Ещё для теста можете вывести ваша переменная $hisaddr, чтобы определить, определяется она или нет.

P.S.: поправьте тему, у вас орфогр. ошибка.


--------------------
PM   Вверх
gers
Дата 20.1.2008, 03:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



Простите исправил в исходное состояние, а название темы чтото не понял как менять  smile

стоят они на разных машинах, проблем с портами быть неможет, дело в том что даже вывод переменной $hishost  остается пустой, а в ней должен быть по идее адрес удаленного хоста, правильно?

нашел еще одну ошибку в 20 строке, это я ее сделал в ходе экспериментов, сейчас исправил:
Код

#!/usr/bin/perl -w

# udpqotd - сервер сообщений UDP
use strict;
use IO::Socket;

my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO, $call, $ipaddr );
$MAXLEN = 1024;
$PORTNO = 1234;
#$LAddr = inet_aton("192.168.2.1");
$sock = IO::Socket::INET->new(LocalAddr => '192.168.2.1', LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@";
$call= IO::Socket::INET->new(PeerPort=>$PORTNO, Proto=>'udp', PeerAddr =>$hishost ) or die "socket: $@";

  print "Awaiting UDP messages on port $PORTNO\n";
  $oldmsg = "This is the starting message.";
  while ($sock->recv($newmsg, $MAXLEN)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
      $hishost = gethostbyaddr($ipaddr, AF_INET);
      
        print "Client $hishost said $newmsg\n";
      $call->send($newmsg);
        #$oldmsg = "[192.168.2.3] $newmsg";
        }
        die "recv: $!";

и ошибка при отправке обратно:
Код

send: Cannot determine peer address at ./udp.pl line 21


Это сообщение отредактировал(а) gers - 20.1.2008, 04:01
PM MAIL   Вверх
nitr
Дата 20.1.2008, 04:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Я увидел, что у вас не определяется ИП smile
Цитата
Client  said  ''test''
, а должно быть примерно Client 192.168.2.3 said  ''test'', значит переменная $hishost (выше я ошибся в названии переменной, но имел эту ввиду, а не $hisaddr) не определяется! Ищите в этом ошибку.

Честно, я даже не вижу откуда вы получаете переменую $hishost.

P.S.: gers, при редактировании сообщения должна быть доступна графа с названием темы, которую и можно отредактировать.

Добавлено через 24 секунды
12-ая строка.

Добавлено через 1 минуту и 38 секунд
Не обращайте внимания, на 18-ую smile


--------------------
PM   Вверх
KSURi
Дата 20.1.2008, 04:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Код

  while ($sock->recv($newmsg, $MAXLEN)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
      $hishost = gethostbyaddr($ipaddr, AF_INET);

Зачем во время цикла каждый раз получать данные, которые не изменяются?
Манипуляции с sockaddr_in и gethostbyaddr можно заменить вызовом одного метода peerhost.
В итоге я сделал бы так:
Код

...
$hishost = $sock->peerhost;
while($sock->recv($newnsg, $MAXLEN)) {
...


Ну и собственно по поводу ошибки:
как уже написал nitr, вы используете неинициализированную переменную $hishost в качестве адреса для подключения.
Однако, не понятно, почему это обнаруживается только при попытке посылки данных, хотя по идее должна была отработать проверка or die "socket: $@"...

Это сообщение отредактировал(а) KSURi - 20.1.2008, 04:42


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
gers
Дата 20.1.2008, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



Спасибо за помощь! но проблема основная осталась, $hishost начала определяться, но в PeerAddr =>$hishost  она толи не доходит толи я торможу, при явной подстановке PeerAddr => '192.168.2.3' все работает. И подскажите где можно почитать про неинициализированные переменные если это с связано с моей проблемой.

Код

#!/usr/bin/perl -w

# udpqotd - сервер сообщений UDP
use strict;
use IO::Socket;

my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO, $call, $ipaddr );
$MAXLEN = 1024;
$PORTNO = 1234;
$sock = IO::Socket::INET->new(LocalAddr => '192.168.2.1', LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@";
$call= IO::Socket::INET->new(PeerPort=>$PORTNO, Proto=>'udp', PeerAddr =>$hishost ) or die "socket: $@";

  print "Awaiting UDP messages on port $PORTNO\n";
  $oldmsg = "This is the starting message.";
  while ($sock->recv($newmsg, $MAXLEN)) {
  $hishost = $sock->peerhost;
    print "Client $hishost said  $newmsg\n";
    $call->send($newmsg);
        print "$hishost\n";
        }
        die "recv: $!";

ответ:
Код

Awaiting UDP messages on port 1234
Client 192.168.2.3 said  sdf
send: Cannot determine peer address at ./udp.pl line 18

PM MAIL   Вверх
KSURi
Дата 20.1.2008, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



gers, уважаемый, вы кажется совсем не поняли, что я и nitr имели ввиду.
Цитата(gers @  20.1.2008,  14:25 Найти цитируемый пост)
но проблема основная осталась, $hishost начала определяться, но в PeerAddr =>$hishost  она толи не доходит толи я торможу

Что вы такое пишете? Где она начала определяться? Давайте посмотрим последний код внимательно:
Цитата(gers @  20.1.2008,  14:25 Найти цитируемый пост)
Код

my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO, $call, $ipaddr ); # Объявлена переменная $hishost. Инициализации нет.
$MAXLEN = 1024; # Инициализируется переменная $MAXLEN
$PORTNO = 1234; # Инициализируется переменная $PORTNO
$sock = IO::Socket::INET->new(LocalAddr => '192.168.2.1', LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@"; # используется инициализированная переменная $PORTNO
$call= IO::Socket::INET->new(PeerPort=>$PORTNO, Proto=>'udp', PeerAddr =>$hishost ) or die "socket: $@"; # А вот здесь вы используете переменную $hishost, но вы ее не инициализировали! Только объявили

Код my $hishost; только объявляет переменную, но не задает ей значение, т.е. грубо говоря, в таблице символов Perl появляется упоминание о $hishost, но сама переменная пуста. Ей надо явно задать значение:
Код

$hishost = '192.168.2.3';

А потом уже подставлять в кач-ве параметра PeerAddr в создании сокета.

Добавлено через 3 минуты и 23 секунды
Цитата(gers @  20.1.2008,  14:25 Найти цитируемый пост)
$hishost = $sock->peerhost;

Метод изменили, а за цикл не вынесли)

Это сообщение отредактировал(а) KSURi - 20.1.2008, 15:01


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
gers
Дата 20.1.2008, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



так дело в том что $hishost = 'удаленный_ip';  меняется в зависимости от адреса запроса, простите что не ясно выразился.
По идее $hishost = $sock->peerhost; должен быть в цикле иначе адрес удаленного хоста не будет менять или я неправ тут?

и так и не разобрался как поправить тему  smile 
само поле темы неизменяемое...


Это сообщение отредактировал(а) gers - 20.1.2008, 15:25
PM MAIL   Вверх
KSURi
Дата 20.1.2008, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Цитата(gers @  20.1.2008,  15:24 Найти цитируемый пост)
так дело в том что $hishost = 'удаленный_ip';  меняется в зависимости от адреса запроса, простите что не ясно выразился.
По идее $hishost = $sock->peerhost; должен быть в цикле иначе адрес удаленного хоста не будет менять или я неправ тут?

Вы что-то совсем непонятное написали =(
В зависимости от какого запроса будет меняться адрес? Где вообще в коде какие-то запросы?

Это сообщение отредактировал(а) KSURi - 20.1.2008, 18:38


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
KSURi
Дата 20.1.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Так, виноват, извиняюсь.
Про peerhost я погорячился: забыл, что имею дело с UDP. Оставьте как есть (я имею ввиду про вынесение за цикл).
Однако, с $hishost все остается в силе: вы используете неинициализрованную переменную в кач-ве адреса для подключения (параметр PeerAddr на строке 11) и не понятно от каких "запросов" она будет зависить.

P.S.: почистил предыдущий пост

Это сообщение отредактировал(а) KSURi - 20.1.2008, 18:42


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
gers
Дата 20.1.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



блин вобщем подразобрался немного, все верно.
$hishost = $sock->peerhost;
$hishost переменная (айпи) возникает когда удаленный клиент посылает сообщение и происходит цикл: узнаем адрес удаленного клиента и посылаем ему ответное сообщение
а проблема в том что PeerAddr =>$hishost должен выглядеть так PeerAddr =>'$hishost'
только непойму как надо в этом случае экранировать переменную внутри ковычек? или переменную желательно заключить в ковычки еще раньше?
PM MAIL   Вверх
nitr
Дата 20.1.2008, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Цитата(gers @  20.1.2008,  19:06 Найти цитируемый пост)
а проблема в том что PeerAddr =>$hishost должен выглядеть так PeerAddr =>'$hishost'

Чушь это.

Я не знаю чего вы хотите получить, но у вас "слишком простое приложение", чтобы назвать его более менее полноценным сервером-клиетом.

udp.pl
Код
#!/usr/bin/perl
use strict;
use warnings;

use IO::Socket;

my ($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO, $ipaddr );
$MAXLEN = 1024;
$PORTNO = 1234;

$sock = IO::Socket::INET->new(LocalAddr => '192.168.2.1', LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@";

print "Awaiting UDP messages on port $PORTNO\n";
$oldmsg = "This is the starting message.";
while ($sock->recv($newmsg, $MAXLEN)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
    my $call= IO::Socket::INET->new(PeerAddr => inet_ntoa($ipaddr), PeerPort => $PORTNO, Proto=> 'udp' ) or die "socket: $@";
    
    $hishost = gethostbyaddr($ipaddr, AF_INET);
    print "Client $hishost said $newmsg\n";
    $call->send($newmsg);
}

die "recv: $!";


client.pl
Код
#!/usr/bin/perl
use strict;
use warnings;

use IO::Socket;

my $call= IO::Socket::INET->new(PeerPort=> '1234', Proto=>'udp', PeerAddr => '192.168.2.1' ) or die "socket: $@";
print $call "Test\n";


Но верно ли это всё?


--------------------
PM   Вверх
gers
Дата 20.1.2008, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 30.9.2007

Репутация: нет
Всего: нет



Большое спасибо за помощь ребята, я немного не стого начал... 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0995 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.