How can I diagnose "Unable to determine ad hoc address" in my Perl TCP script?

I have this little script that does the job pretty well, but sometimes it fails. This fails in 2 cases:

  • with error message: Cannot determine peer address at ./tcp-new.pl line 52

  • without output or anything else, it simply cannot deliver what it received to the connected Tcp Client. This usually happens after I disconnect from the server, go home and reconnect it. To fix this restart is required, and it starts to work. Sometimes this problem is followed by the problem mentioned in paragraph 1.

Note: this is not a problem when I disconnect and reconnect to it for a short period of time (unless error number 1 occurred).

So can someone help me make this code a little more stable, so I don’t need to restart it every day?

 #!/usr/bin/perl use strict; use warnings; use IO::Socket; use IO::Select; my $tcp_port = "10008"; my $udp_port = "2099"; my $tcp_socket = IO::Socket::INET->new( Listen => SOMAXCONN, LocalPort => $tcp_port, Proto => 'tcp', ReuseAddr => 1, ); my $udp_socket = IO::Socket::INET->new( LocalPort => $udp_port, Proto => 'udp', ); my $read_select = IO::Select->new(); my $write_select = IO::Select->new(); $read_select->add($tcp_socket); $read_select->add($udp_socket); while (1) { my @read = $read_select->can_read(); foreach my $read (@read) { if ($read == $tcp_socket) { my $new_tcp = $read->accept(); $write_select->add($new_tcp); } elsif ($read == $udp_socket) { my $recv_buffer; $udp_socket->recv($recv_buffer, 1024, undef); my @write = $write_select->can_write(); foreach my $write (@write) { $write->send($recv_buffer); } } } } 
+4
source share
3 answers

The Cannot determine peer address error means getpeername() returns false. This probably means that the socket was closed on the other hand, perhaps between a call to can_write() and send . You should probably remove it from the selection set and move on.

+2
source

Found the same problem as a sock without a peeraddress.

A look at IO :: Socket at http://search.cpan.org/src/GBARR/IO-1.2301/IO/Socket.pm shows:

 sub send { @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]] +)'; my $sock = $_[0]; my $flags = $_[2] || 0; my $peer = $_[3] || $sock->peername; croak 'send: Cannot determine peer address' unless($peer); 

Thus, you must ensure that either the username is initialized when the object is created, or a peer name is provided as the third argument to send ().

 if (! $sock->peeraddr()) { $log->warn("No peer, will croak!"); } 
+1
source

In a scenario where your script crashes without errors, this is probably due to an unprocessed signal, usually SIGPIPE. This can happen if a socket operation receives a signal during a send operation. I can play it quite easily on my systems, simulating a lot of simultaneous connections of a large amount of data to the tcp server and at the same time killing these client connections. Run strace on your script and you can see the signal quite clearly. However, I am trying to figure out how to reproduce the error "Unable to determine the peer network address", but to no avail ....

0
source

Source: https://habr.com/ru/post/1302035/


All Articles