thanos1983 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

The answer to my question probably is really simple but I can not figure it out.

I am trying to make my server running on PeerAddr and PeerPort. Based on my current settings my server is running on localhost. I found my current allocated IP and assigned it to the server and also I chosen randomly 5000 port number for the file descriptors.

When the server is running on localhost the client can send and receive the messages. When I am assigning the servers PeerAddr an external IP not the localhost then I get the following error:

Client error while received: Connection refused

Since so far I have only been experimenting on localhost can someone help me understand where I am going wrong and the server can not operate on external addresses.

Sample of server.pl code:

#!/usr/bin/perl use strict; use warnings; use IO::Socket::INET; my $port = 5000; my $IP = "127.0.0.1"; # flush after every write $| = 1; my $server_socket = IO::Socket::INET->new( #PeerAddr => inet_ntoa(INADDR_BROADCAST), PeerPort => $port, PeerAddr => $IP, #LocalPort => $port, Proto => 'udp', Type => SOCK_DGRAM, LocalAddr => 'localhost', Broadcast => 1, ReuseAddr => 1, ReusePort => 1 ) or die "Can't bind: $@\n"; my $recieved_data; printf("\nServer is up, listens on PORT: ".$port." waiting for client. +..\n"); while (1) { # read operation on the socket $server_socket->recv( $recieved_data , 1024 ) or die "Server error received: $!\n"; #get the peerhost and peerport at which the recent data received. my $peer_address = $server_socket->peerhost(); my $peer_port = $server_socket->peerport(); print "\n($peer_address , $peer_port) said : $recieved_data"; #send the data to the client at which the read/write operations do +ne recently. my $data = "Echo: ".$recieved_data.""; $server_socket->send( $data ) or die "Server error send: $!\n"; } $server_socket->close();

Sample of client.pl code:

#!/usr/bin/perl use strict; use warnings; use IO::Socket::INET; my $port = 5000; my $IP = "127.0.0.1"; # flush after every write $| = 1; my $client_socket = new IO::Socket::INET ( PeerHost => $IP, Type => SOCK_DGRAM, PeerPort => $port, Proto => 'udp' ) or die "ERROR in Socket Creation: $@\n"; my $Peer_Port = $client_socket->peerport(); my $data_send = "Test!!!!!"; $client_socket->send( $data_send ) or die "Client error while sending: $!\n"; #read operation $client_socket->recv( my $data_rcv , 1024 ) or die "Client error while received: $!\n"; print "Received data: $data_rcv\n"; $client_socket->close();

Thanks in advance for your time and effort.

Seeking for Perl wisdom...on the process of learning...not there...yet!

Replies are listed 'Best First'.
Re: UDP server/client Connection refused
by NetWallah (Canon) on Sep 26, 2014 at 04:29 UTC
    By setting
    LocalAddr => 'localhost',
    on the $server_socket in the server code, you are limiting it to listening only on the local loopback address.

    Delete that line, or set the LocalAddr to "0.0.0.0" , which allows binding to ANY available local IP address.

    This will enable connections from outside the local 127.0.0.0 network to connect.

            "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams

      Hello NetWallah,

      Thank you for your time and effort, reading and replying to my question.

      After some experimentation I finally understood that PeerAddr on the server side has to combined with the LocalPort, because is the server port locally and it will use this port for communication with the clients.

      The only part that I still can not understand is on the server side, it dose not really matters what king of modification I am applying on the LocalAddr => 'localhost', or LocalAddr => "0.0.0.0", still can not communicate locally. I was under the impression that local communication is different than external.

      Last question just in case you know about it. I found on IO::Socket::INET the following part of code:

      $sock = IO::Socket::INET->new( PeerPort => 9999, PeerAddr => inet_ntoa(INADDR_BROADCAST), Proto => udp, LocalAddr => 'localhost', Broadcast => 1 ) or die "Can't bind : $@\n";

      I was trying to understand the use of PeerAddr  => inet_ntoa(INADDR_BROADCAST),. I was looking online and I found 8.2 The IP address INADDR_BROADCAST where it explains:

      If there is a socket that is bound to the address assigned to the interface from which the packet was received, the packet will be delivered to this socket.

      I was under the impression that if there is a socket available on the server side, then it can be used for communication but so far I did not found a way to use it. But maybe I did not understand correctly.

      Any way thank you again for your time and effort.

      Seeking for Perl wisdom...on the process of learning...not there...yet!
        I believe you derived your code from http://www.thegeekstuff.com/2010/07/perl-tcp-udp-socket-programming/.

        I modified/simplified the code, and this set works fine for me:
        SERVER:

        #!/usr/bin/perl #udpserver.pl use strict; use warnings; use IO::Socket::INET; $| = 1; # flush after every write my $socket = new IO::Socket::INET ( LocalPort => '5000', Proto => 'udp', ) or die "ERROR in Socket Creation : $!\n"; while(1){ $socket->recv(my $recieved_data,1024); my $peer_address = $socket->peerhost(); my $peer_port = $socket->peerport(); print "\n($peer_address , $peer_port) said : $recieved_data"; #send the data to the client at which the read/write operations do +ne recently. $socket->send ("Server received '$recieved_data'. This is the SERV +ER response\n"); } $socket->close(); # We will never get here , but good practice to clos +e
        CLIENT:
        #!/usr/bin/perl #udpclient.pl use strict; use warnings; use IO::Socket::INET; $| = 1; # flush after every write my $socket = new IO::Socket::INET ( PeerAddr => '127.0.0.1:5000', Proto => 'udp' ) or die "ERROR in Socket Creation : $!\n"; $socket->send("data from client"); $socket->recv(my $data,1024); print "Data received from socket : $data\n"; $socket->close();
        The BROADCAST is a way to send data to all listeners on the subnet. To do that, you use a special broadcast IP addressto SEND data.

        I'm not sure I understood your question in this regard.

                "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams