Receive replies to a UDP broadcast

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • OBones

    Receive replies to a UDP broadcast

    Hi all,

    I'm currently trying to receive replies to a UDP broadcast that I sent
    and I can't get it to work. I know the datagrams are sent as I see
    them with WireShark, but my C# code does not see them.
    Here is how I intended things to work:

    Socket socket = new Socket(AddressF amily.InterNetw ork,
    SocketType.Dgra m, ProtocolType.Ud p);
    try
    {
    // Send data to the broadcast address
    IPEndPoint broadcastIEP = new IPEndPoint(IPAd dress.Broadcast ,
    port);
    socket.Connect( broadcastIEP);
    socket.Send(dat a);

    // Wait for someone to respond
    for (int i = 0; i < 50; i++)
    {
    int availableBytes = socket.Availabl e;
    if (availableBytes 0)
    {
    byte[] buffer = new byte[availableBytes];
    socket.Receive( buffer, 0, availableBytes,
    SocketFlags.Non e);

    return ASCIIEncoding.A SCII.GetString( buffer);
    }
    System.Threadin g.Thread.Sleep( 100);
    }
    return "Nobody replied";
    }
    finally
    {
    socket.Close();
    }


    The intent is to send a UDP broadcast and wait for the first machine
    that replies. The wait should stop after a while.
    I must be doing something wrong here, but I'm quite lost as to what I
    should be doing. I tried "ReceiveFro m", but it is a blocking call and
    it never seems to return. I see the datagrams coming through (using
    WireShark) but ReceiveFrom does not return.

    Thanks for your help
    Cheers
    Olivier
  • not_a_commie

    #2
    Re: Receive replies to a UDP broadcast

    There is a whole slew of things that could be the issue here. In the
    first place, you should be listening before you send. You'll need to
    make another thread to do that or use the BeginReceive method. Second,
    don't use the Available property. It's busted. Use the return value on
    Receive to know how much data was put into your buffer instead. Third,
    I'm pretty sure you'll need to bind to a port (with the Bind method)
    to receive any data. In other words, you may need two sockets here.
    One to send and one to receive. You may also need to set the option on
    the sockets to allow multiple sockets to bind to the same address.

    Comment

    • Peter Duniho

      #3
      Re: Receive replies to a UDP broadcast

      On Wed, 05 Nov 2008 04:36:52 -0800, OBones <obones@gmail.c omwrote:
      Hi all,
      >
      I'm currently trying to receive replies to a UDP broadcast that I sent
      and I can't get it to work. I know the datagrams are sent as I see
      them with WireShark, but my C# code does not see them.
      The reply from the person posting as "not_a_comm ie" has a lot of good
      suggestions in it. I think that the one most directly applicable to the
      immediate issue is that you don't try to receive from the socket until
      after you've sent something. With UDP, if you aren't ready to receive
      data already when someone else sends data, it's entirely possible that the
      network driver will just drop the data altogether and you'll never see it.

      You _should_ be able to send and receive broadcast data on the same
      socket, but you need to bind the socket to the same IPAddress.Broad cast
      address for that to work. Of course, for you to be ready to receive at
      the same time you send data on the socket, you'll have to either use the
      asynchronous API and call BeginReceive() or have another thread that calls
      Receive() before you call Send().

      Finally, it's not so much that the Available property is broken, as it is
      that it just doesn't really do what most people expect it to do. Network
      sockets don't behave exactly the same as other i/o interfaces; in
      particular data can come and go without any action on the part of the
      client code, depending on the needs of the network driver to manage all of
      the network i/o going on at the time. Just because the Available property
      indicates there's data to be read, that doesn't mean that by the time you
      try to read it, it will still be there.

      So, you need a different way of implementing your timeout logic. Since
      you're using UDP, I'd say you could probably get away with just setting
      the Socket.ReceiveT imeout property (using that with TCP introduces as many
      problems as it solves, so you're better off without it in that case...but
      UDP should be fine).

      I'm not sure that even between our two posts, you have every bit of
      information you're going to need to get this work right, but hopefully
      it's a nudge in the right direction. :)

      Pete

      Comment

      Working...