in reply to Re^2: Sending AND Receiving on the Same Port
in thread Sending AND Receiving on the Same Port

It appears the issue is that I can't listen on the same socket I broadcast on. Am I right on this?

That makes no sense. Each message is completely independent in UDP. You can send to anyone and receive from anyone with a single socket.

in the time it takes to make a new socket, won't data be incoming and lost?

Why would someone be sending to a socket you haven't created yet?

  • Comment on Re^3: Sending AND Receiving on the Same Port

Replies are listed 'Best First'.
Re^4: Sending AND Receiving on the Same Port
by HalNineThousand (Beadle) on Feb 24, 2011 at 02:53 UTC

    I can see how each message is separate, but when I create a socket to broadcast, I have to specify it's for broadcasting:

    $sender = IO::Socket::INET->new( PeerAddr => inet_ntoa(INADDR_BROADCAST), Broadcast => 1, PeerPort => '7071', Proto => 'udp' ) or die "cannot connect: $!\n";

    So once I do this, doesn't that change the nature of the socket? I don't see a method in IO::Socket::INET or IO::Socket that lets me change the Broadcast flag to 0 after I send a broadcast. I've been trying with sockopt(), but it won't set or change any values.

      No, you don't have to connect to INADDR_BROADCAST.

      use strict; use warnings; use IO::Socket::INET qw( INADDR_BROADCAST inet_ntoa pack_sockaddr_in u +npack_sockaddr_in ); use threads ;#qw( async ); my $client = async { my $s = IO::Socket::INET->new( Proto => 'udp', LocalPort => 7071, Broadcast => 1, ) or die("Can't create socket: $!\n"); defined( my $peer = $s->recv(my $msg, 64*1024, 0) ) or die("Can't recv: $!\n"); my ($port, $addr) = unpack_sockaddr_in($peer); $addr = inet_ntoa($addr); print("Received $msg from $addr:$port\n"); $s->send("Pong!", 0, $peer); }; { my $s = IO::Socket::INET->new( Proto => 'udp', Broadcast => 1, ) or die("Can't create socket: $!\n"); $s->send("Ping!", 0, pack_sockaddr_in(7071, INADDR_BROADCAST)); defined( my $peer = $s->recv(my $msg, 64*1024, 0) ) or die("Can't recv: $!\n"); my ($port, $addr) = unpack_sockaddr_in($peer); $addr = inet_ntoa($addr); print("Received $msg from $addr:$port\n"); } $client->join();
      Received Ping! from 10.0.0.6:49853 Received Pong! from 10.0.0.6:7071

      I have to specify it's for broadcasting [...] doesn't that change the nature of the socket?

      I think it simply allows it to broadcast and receive broadcasts.

      What catches my eye is that you chose to connect to INADDR_BROADCAST. Connecting a UDP socket (i.e. specifying PeerAddr) means you can only receive from the address to which you connect. What does it mean to connect to INADDR_BROADCAST? ( Can only receive broadcasts ) Do you have to connect to INADDR_BROADCAST? ( no ) Will test tomorrow.

      I don't see a method in IO::Socket::INET or IO::Socket that lets me change the Broadcast flag to 0 after I send a broadcast.

      Since Broadcast=>1 does

      $sock->sockopt(SO_BROADCAST,1)

      the approach would be

      $sock->sockopt(SO_BROADCAST,0)

      But again, I don't think this is necessary.

Re^4: Sending AND Receiving on the Same Port
by HalNineThousand (Beadle) on Feb 24, 2011 at 17:35 UTC
    Thank you for all the help on this!

    Once I studied your code and altered mine and got tests working, I found other issues with xinetd and UDP, so, in the long run, I had to send the "Where are you" message on one port, then the server had to reply on a different port. I tried using the same port for the server, but I couldn't open a 2nd socket there using the same port.

    While the solution didn't come directly from what you showed me, your code helped me fix what I had wrong there and let to me finding the root issue.

    Thanks!