C#Winforms UDPClient异常:“通常只允许使用每个套接字地址。”

时间:2017-02-24 00:46:19

标签: c# .net windows sockets networking

我正在使用C#/ Winforms中的GUI,通过UDP与另一个系统进行通信。我正在使用DotNet'UdpClient'类。我正在为每次传输使用一个插槽,并且一个用于接收:

UdpClient client = new UdpClient(receiveport_num);
client.Client.SetSocketOption(SocketOptionLevel.Socket,     SocketOptionName.ReuseAddress, true);
client.Client.SetSocketOption(SocketOptionLevel.Socket,     SocketOptionName.ExclusiveAddressUse, false);
client.BeginReceive(DataReceived, client);

UdpClient server = new UdpClient(ConnectionSettings.soport);
server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false);

然后使用server.Send。

从'server'套接字接收

一旦我完成套接字,或者应用程序关闭,它们将被处理掉:

client.Client.Shutdown(SocketShutdown.Both);
client.Client.Close();
client.Close();
client = null;

server.Client.Shutdown(SocketShutdown.Both);
server.Client.Close();
server.Close();
server = null;

出于某种原因,如果我尝试重新创建这些套接字,无论是通过再次创建套接字还是重新启动应用程序,我都会遇到异常:

System: Only one usage of each socket address (protocol/network) is normally permitted.

我理解这是因为即使我关闭了套接字,底层的Windows套接字仍然存在,因为Windows让它们保持活力......

我想使用相同的端口号并每次重新创建套接字。我怎样才能做到这一点?如果这是不可能的(如果你问我,这听起来像Windows中的一个网络问题......),那么有没有办法可以重新获得套接字供我使用?

1 个答案:

答案 0 :(得分:1)

我发现了问题。我的应用程序是使用Process.Start(ProcessStartInfo pi)生成进程。使用此函数时,属于主应用程序进程的所有句柄(包括套接字)都由子进程继承。

当父进程死亡时,子进程仍处于活动状态,保持套接字打开。这可以通过以下两种方式之一解决:

a)使用P / Invoke,将Process.Start替换为createprocess(),将bInheritHandles设置为false。据我所知,dotNet Process.Start函数没有任何等价物,我认为这是一种疏忽。

b)使用P / Invoke,在创建每个套接字后,您不希望子进程继承,使用INHERIT作为dwMask参数调用SetHandleInformation(),并{ {1}}作为NONE参数。