The following code, although it obviously closes the UDP socket, leaves it hanging and cannot reconnect to the same address / port.
These are the class variables that I use:
Thread t_listener; List<string> XSensAvailablePorts; private volatile bool stopT_listener = false; volatile UdpClient listener; IPEndPoint groupEP;
I create and start a new thread using a method that will handle the Socket connection and listening:
private void startSocketButton_Click(object sender, RoutedEventArgs e) { stopT_listener = false; closeSocketButton.IsEnabled = true; startSocketButton.IsEnabled = false; t_listener = new Thread(UDPListener); t_listener.Name = "UDPListenerThread"; t_listener.Start(); }
The method is as follows (I use timeOut in Receive so as not to leave it blocked if nothing is sent on the socket and Stop is issued):
private void UDPListener() { int numberOfPorts = XSensAvailablePorts.Count(); int currAttempt = 0; int currPort = 0; bool successfullAttempt = false; while (!successfullAttempt && currAttempt < numberOfPorts) { try { currPort = Int32.Parse(XSensAvailablePorts[currAttempt]); listener = new UdpClient(currPort); successfullAttempt = true; } catch (Exception e) { currAttempt++; } } if (successfullAttempt) { //timeout = 2000 millis listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000); //Tried with and without, no change: listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); statusTB.Dispatcher.BeginInvoke((Action)delegate() { statusTB.Text = "Connected on port:" + currPort; }); groupEP = new IPEndPoint(IPAddress.Parse("143.225.85.130"), currPort); byte[] receive_byte_array; try { while (!stopT_listener) { try { receive_byte_array = listener.Receive(ref groupEP); if (receive_byte_array.Length == 0 || receive_byte_array == null) continue; ParseData(receive_byte_array, samplingDatagramCounter); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.TimedOut) continue; } } } catch (Exception e) { Debug.Print(e.Message); } finally { if (listener != null) { listener.Client.Shutdown(SocketShutdown.Both); listener.Close(); } } } statusTB.Dispatcher.BeginInvoke((Action)delegate() { statusTB.Text = "Not Connected"; }); return; }
I command to stop the stream / socket with this method:
private void closeSocketButton_Click(object sender, RoutedEventArgs e) { stopT_listener = true; closeSocketButton.IsEnabled = false; startSocketButton.IsEnabled = true; t_listener.Join(); if (listener.Client != null) { listener.Client.Shutdown(SocketShutdown.Both); listener.Close(); } if (t_listener.IsAlive) { t_listener.Abort(); statusTB.Text = "Aborted"; } else statusTB.Text = "Not Connected"; }
Although the debugging check that the socket was closed if I try to connect to the same port, I cannot do this because it raises a SocketException, which usually only allows one port / address use.