Может кто-нибудь объяснить, почему мой сервер / клиент не работает так, как они устанавливают соединение?

#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: $!";
  

Рекомендация: быстрый просмотр следующих страниц поможет вам в программировании