Tutorial :Why do I receive twice the data sent over UDP broadcast?



Question:

I have a problem with the code below. What it does is send the current date/time using UDP broadcast and listens to this message. My current use of this code is local, I use the Send and Receive in the same application, on the same computer. I didn't try it between 2 computers yet.

public class Agent  {      public static int Port = 33333;      public delegate void OnMessageHandler(string message);        Socket socketSend;      Socket socketReceive;        bool receiving = false;      Thread receiveThread;        public event OnMessageHandler OnMessage;        public Agent()      {          socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);          socketSend.EnableBroadcast = true;            socketSend.Connect(new IPEndPoint(IPAddress.Broadcast, Port));            socketReceive = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);          socketReceive.EnableBroadcast = true;            socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));      }        public void Start()      {          Console.WriteLine("Agent started!");            receiving = true;          receiveThread = new Thread(new ThreadStart(Receive));          receiveThread.IsBackground = true;          receiveThread.Start();      }        public void Stop()      {          receiving = false;            socketSend.Close();          socketReceive.Close();            receiveThread.Join();            Console.WriteLine("Agent ended.");      }        public void Send(string message)      {          Console.WriteLine("Sending : {0}", message);          byte[] bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(message));          socketSend.Send(bytes);          Console.WriteLine("Message sent.");      }        protected void Receive()      {          Console.WriteLine("Thread started!");          while (receiving)          {              try              {                  if (socketReceive.Available > 0)                  {                      byte[] bytes = new byte[socketReceive.Available];                        Console.WriteLine("Waiting for receive...");                        int bytesReceived = socketReceive.Receive(bytes, SocketFlags.None);                      Console.WriteLine("Bytes received : {0}", bytesReceived);                        string message = Encoding.UTF8.GetString(bytes);                      Console.WriteLine("Received message : {0}", message);                      OnMessage(message);                  }                  else                  {                      Console.Write(".");                      Thread.Sleep(200);                  }              }              catch (SocketException ex)              {                  if (ex.SocketErrorCode == SocketError.Interrupted)                  {                      break;                  }                  else                  {                      throw;                  }              }          }          Console.WriteLine("Thread ended.");      }  }  

The problem I have is that it sends the data once (when I click on a button) but it receives twice the amount expected. For example, a normal date/time is 19 bytes long but the first time Available is > 0, its value is 38. The Receive call following only grabs 19 bytes and the loop continues with the next 19 bytes. That means I receive my message and twice and I want it only once of course.

Example of an output :

Agent started!  Thread started!  ..........Sending : 29/07/2009 12:05:04  Message sent.  Waiting for receive...  Bytes received : 19  Received message : 29/07/2009 12:05:04  Waiting for receive...  Bytes received : 19  Received message : 29/07/2009 12:05:04  ......Thread ended.  Agent ended.  


Solution:1

socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));  

By binding to all your IP addresses, you'll be getting local loopback and via the network as well.


Solution:2

I'd advise you to try this on a specified target IP first. This way the network topography will have less of an effect, and you can just move it to a broadcast address when everything works the way you expect.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »