Sav*_*ano 6 .net c# sockets multithreading udpclient
以下代码尽管显然关闭了UDP套接字,但仍然无法重新连接到同一个地址/端口.
这些是我使用的类变量:
Thread t_listener;
List<string> XSensAvailablePorts;
private volatile bool stopT_listener = false;
volatile UdpClient listener;
IPEndPoint groupEP;
Run Code Online (Sandbox Code Playgroud)
我用一个处理Socket连接和监听的方法创建并启动一个新线程:
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();
}
Run Code Online (Sandbox Code Playgroud)
该方法如下(我使用超时Receive,以便在套接字上没有发送任何内容并且正在发出时不会阻止它Stop):
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;
}
Run Code Online (Sandbox Code Playgroud)
我命令线程/套接字停止使用此方法:
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";
}
Run Code Online (Sandbox Code Playgroud)
尽管在调试中检查了套接字已经关闭,但是如果我重试连接到同一个端口,我无法这样做,因为它引发了一种SocketException说法,即通常只允许使用一次端口/地址.
我将您提供的代码以简单的形式运行它并且...我无法直接重现您的问题。不过,我还没有向客户端发送任何数据,但据我了解,它不应该改变任何内容,因为它是 UDP,并且我们正在研究(重新)打开套接字,而不是传输数据。
单击“开始/停止”按钮时,套接字始终正确打开和关闭,重新打开按预期工作。对我来说,强制您提到的 SocketException 的唯一方法是引入一些明显的套接字逻辑误用:
我在代码中所做的唯一更改是删除 ParseData(...) 行并将一些端口添加到 XSensAvailablePorts 列表。
您可以检查端口在您明显关闭后是否仍然打开吗?您可以使用netstat -an,或者一个优秀的工具ProcessExplorer。您还可以检查 t_listener 线程是否正确终止(标准任务管理器或 ProcessExplorer 可以帮助您)。
| 归档时间: |
|
| 查看次数: |
2540 次 |
| 最近记录: |