#perl
#perl
Вопрос:
Я начинаю работать с сокетами и пытаюсь создать клиент и сервер, с которых клиент подключается к серверу, не разрывая контакт после того, как сообщение было доставлено на сервер или наоборот.
Проблема, с которой я сталкиваюсь, заключается в том, что они оба ничего не выводят (я вижу, что сервер прослушивает, а клиент останавливается напрямую, ничего не выводя)
Обе программы не содержат никаких лексических ошибок.
Вот код клиента:
#!/usr/bin/perl -w
use strict;
use diagnostics;
use Socket;
my $port = somedigits;
my $server_addr = "somebits.somebits.somebits.somebits";
sub open_TCP
{
# get parameters
my ($FS, $server_addr, $port) = @_;
my $proto = getprotobyname('tcp');
socket($FS, PF_INET, SOCK_STREAM, $proto);
my $sin = sockaddr_in($port,inet_aton($server_addr));
connect($FS,$sin) || return undef;
my $old_fh = select($FS);
$| = 1; # don't buffer output
select($old_fh);
1;
}
1;
amp;open_TCP;
Вот код сервера:
#!/usr/bin/perl -w
use strict;
use diagnostics;
use Socket;
my $port = somedigits;
my $server_addr = "somebits.somebits.somebits.somebits";
socket(my $socket, PF_INET, SOCK_STREAM, getprotobyname("tcp")) or die $!; # initalize socket
bind($socket, pack_sockaddr_in($port, inet_aton($server_addr))) # associate socket with port
or die("can't bind to port:" . $port);
listen($socket, 5) # start listening
or die $1;
while(my $incoming_client = accept(my $new_socket, $socket)) { # accept incoming connections
my $hostname = gethostbyaddr($incoming_client, AF_INET);
sleep 2;
print $new_socket "someoutput" . time() . "n";
printf("Connection from: $hostname");
close $new_socket;
};
Комментарии:
1. Совет: IO ::Socket::IP упрощает написание такого кода и делает его более читаемым.
2. Спасибо за советы, проблема, с которой я сталкиваюсь, заключается в том, что они оба ничего не выводят (я вижу, что сервер прослушивает, и клиент останавливается напрямую, ничего не выводя).
Ответ №1:
-
В клиенте sub
$server_addr
неинициализирован, поскольку вы не передаете никаких аргументов sub. -
В клиенте sub
$port
неинициализирован, поскольку вы не передаете никаких аргументов sub. -
Исправьте вышесказанное, и это сработает. Однако вы можете подумать, что это не работает, потому что вы не очищаете свой вывод.
printf("Connection from: $hostnamen");
Для этого достаточно использовать, когда стандартный вывод подключен к терминалу. -
Наконец,
my $hostname = gethostbyaddr($incoming_client, AF_INET);
должно быть
my ($port, $packed_addr) = unpack_sockaddr_in($incoming_client); my $hostname = gethostbyaddr($packed_addr, AF_INET);
-
Кстати,
if(!$incoming_client)
проверка бесполезна, поскольку вы не достигаете этого утверждения, если$incoming_client
оно равно false .
Комментарии:
1. Какие изменения вы предлагаете для реализации ваших пунктов 1 и 2 в вашем ответе (комментарии приветствуются)?
2.
sub open_TCP { my $server_addr, $port) = @_; my $FS; ... } open_TCP($server_addr, $port);
Ответ №2:
Следующие примеры демонстрируют простой сетевой сервер и клиент.
Пример server.pl
use strict;
use warnings;
use feature 'say';
use Socket;
my $server = 'localhost';
my $port = shift || 6000;
my $proto = getprotobyname('tcp');
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "Can't open socket $!";
bind(SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "Can't bind to port $port!";
listen(SOCKET, 5) or die "listen: $!";
say "SERVER: listen on $port";
while( my $client_addr = accept(NEW_SOCKET, SOCKET)) {
my($port, $iaddr) = sockaddr_in($client_addr);
my $name = gethostbyaddr($iaddr, AF_INET);
my $ip = inet_ntoa($iaddr);
say "CLIENT: connection from $name $ip at port $port";
print NEW_SOCKET "SERVER: localtime is " . localtime();
close NEW_SOCKET;
}
Пример client.pl
use strict;
use warnings;
use feature 'say';
use Socket;
my $server = shift || 'localhost';
my $port = shift || 6000;
my $proto = getprotobyname('tcp');
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
or die "Can't create a socket $!";
connect(SOCKET, pack_sockaddr_in($port, inet_aton($server)))
or die "Can't connect to port $port!";
while( <SOCKET> ) {
say;
}
close SOCKET or die "CLOSE: $!";
Рекомендация: быстрый просмотр следующих страниц поможет вам в программировании