需求:通过UDP侦听当前路由的8000端口,收到指定协定指令返还本机ip,
代码(伪代码):
Thread thrRecv;
/// /// 本地IP地址 ///
private IPAddress MyIPAddress;
/// <summary>
/// 用于UDP接收的网络服务类
/// </summary>
private UdpClient udpcRecv;
private Boolean udpFlag;
//UDPClint对象创建
private void runing()
{
//获取本机可用IP地址
IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress ipa in ips)
{
if (ipa.AddressFamily == AddressFamily.InterNetwork)
{
MyIPAddress = ipa;//获取本地IP地址
// break语句,这个for循环就会立即终止,不在进行其他的迭代了。
break;
}
}
IPEndPoint localIpep = new IPEndPoint(MyIPAddress, 8000); // 本机IP和监听端口号
udpcRecv = new UdpClient(localIpep);
thrRecv = new Thread(ReceiveMessage);
thrRecv.Start();
}
private void ReceiveMessage(object obj)
{
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);
string message = "";
udpFlag = true;
while (udpFlag)
{
try
{
mudpcRecv.Send(”需要发送的数组“, "数组长度", remoteIpep);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("{0}[{1}]", remoteIpep, ex));
break;
}
}
}
UDP对象关闭:
public void stopRuning()
{
this.udpFlag = false;
try {
thrRecv.Abort(); //强制关闭线程
}
catch(Exception e)
{
Console.WriteLine("线程关闭异常");
}
}
当调用两次或者两次的以上的runing()方法触发
:“System.Net.Sockets.SocketException:“通常每个套接字地址(协议/网络地址/端口)只允许使用一次
查看任务管理的侦听端口发现UDP 端口8000还在,线程虽然已经关闭但是线程创建的UDPClinet对象引用还在,即端口被UDPClint持有并未释放(也许GC会去回收了,但是这点我并未验证),所有再次调用runing()方法触发了以上异常
解决方案如下:
调用 udpcRecv.Close();再关闭线程