How to send a message and receive a response on the same socket

I have the following code that sends a multicast message and then waits for a response to be sent to the address where the message came from. If I look at the traffic in Wireshark, I see that the message is sending normally, and the response returns to the correct IP and port, however, the socket never returns from the receive line, as the response is not matched.

var multicastAddress = IPAddress.Parse("239.255.255.250"); var multicastPort = 1900; var unicastPort = 1901; using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { socket.Bind(new IPEndPoint(IPAddress.Any, unicastPort)); socket.Connect(new IPEndPoint(multicastAddress, multicastPort)); var thd = new Thread(() => { try { while (true) { var response = new byte[8000]; EndPoint ep = new IPEndPoint(IPAddress.Any, unicastPort); socket.ReceiveFrom(response, ref ep); var str = Encoding.UTF8.GetString(response); Devices.Add(new SsdpDevice() {Location = str}); } } catch { //TODO handle exception for when connection closes } }); socket.Send(broadcastMessage, 0, broadcastMessage.Length, SocketFlags.None); thd.Start(); Thread.Sleep(30000); socket.Close(); } 

I know that I have to use asynchronous methods in the socket class and you need to stop relying on Thread.Sleep, but I just want a simple example to work before I remove the code.

+4
source share
1 answer

Gavin, check this out:

  • Do not use different ports. How do you expect multicast one by one and receive another?
  • Do not use Connect() , multicasting is sending messages without establishing a connection (just like broadcasting).
  • Set the socket option for multicast after Bind() .
  • Use SendTo() instead of Send() , which will not work in this case.
  • First start (even in lock mode, this is another endpoint), then send.

And a simple working example:

 var broadcastMessage = Encoding.UTF8.GetBytes("Hello multicast!"); var multicastAddress = IPAddress.Parse("239.255.255.250"); var signal = new ManualResetEvent(false); var multicastPort = 1900; using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { var multicastEp = new IPEndPoint(multicastAddress, multicastPort); EndPoint localEp = new IPEndPoint(IPAddress.Any, multicastPort); // Might want to set this: //socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); socket.Bind(localEp); socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastAddress, IPAddress.Any)); // May want to set this: //socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 0); // only LAN var thd = new Thread(() => { var response = new byte[8000]; socket.ReceiveFrom(response, ref localEp); var str = Encoding.UTF8.GetString(response).TrimEnd('\0'); Console.WriteLine("[RECV] {0}", str); signal.Set(); Console.WriteLine("Receiver terminating..."); }); signal.Reset(); thd.Start(); socket.SendTo(broadcastMessage, 0, broadcastMessage.Length, SocketFlags.None, multicastEp); Console.WriteLine("[SEND] {0}", Encoding.UTF8.GetString(broadcastMessage)); signal.WaitOne(); Console.WriteLine("Multicaster terminating..."); socket.Close(); Console.WriteLine("Press any key."); Console.ReadKey(); } 
+9
source

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


All Articles