不知道大家有没有遇见,UdpClient在监听的时候,不管同步还是异步的,调用Close()方法或者调用线程的Abort()方法,会抛出一个异常或者出现一个正在终止线程的小窗体,我理解是UdpClient正在等待接收,线程阻塞了,所以不能强制关闭Udp连接,这个问题我在网上找了好久都没有找到好的解决方法,当时为了不让弹出那个正在终止线程的小框框,我用System.Environment.Exit(0)方法勉强的实现了,最近我自己想出了一个解决的方法,因为Udp连接正在等待接收呢,只要让Udp连接接收到数据,这时就可以正常的Close()了,这样关闭Udp连接的时候不会出现任何异常,下面是我的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
class
Program
{
// UDP连接
static
UdpClient udpClient;
// 本机端口
static
int
localhostPort;
// 本机IP
static
IPAddress localhostIPAddress;
// 本机节点
static
IPEndPoint localhostIPEndPoint;
// 远程主机结点
static
IPEndPoint tempEnd =
new
IPEndPoint(IPAddress.Any, 0);
// 判断是是否释放Udp连接
static
bool
isUdpNull =
default
(
bool
);
static
void
Main(
string
[] args)
{
// 初始化
Init();
// 异步接收
udpClient.BeginReceive(
new
AsyncCallback(ReceiveCallback),
null
);
byte
[] datagram = Encoding.UTF8.GetBytes(
"这是一个测试!!!"
);
//异步发送
udpClient.BeginSend(datagram, datagram.Length, localhostIPEndPoint,
new
AsyncCallback(SendCallback), udpClient);
// 停止异步接收
StopAsynchronousReceive();
Console.ReadKey();
}
// 初始化
static
void
Init()
{
localhostPort = 9000;
localhostIPAddress = IPAddress.Parse(
"127.0.0.1"
);
localhostIPEndPoint =
new
IPEndPoint(localhostIPAddress, localhostPort);
// 将UDP连接绑定终结点
udpClient =
new
UdpClient(localhostIPEndPoint);
}
// 停止异步接收
static
void
StopAsynchronousReceive()
{
byte
[] datagram =
new
byte
[] { 0xff };
udpClient.Send(datagram, datagram.Length, localhostIPEndPoint);
}
// 异步接收回调方法
static
void
ReceiveCallback(IAsyncResult ar)
{
object
o =
new
object
();
try
{
lock
(o)
{
byte
[] buffer = udpClient.EndReceive(ar,
ref
tempEnd);
if
(tempEnd.Equals(localhostIPEndPoint) && buffer[0] == 0xff)
{
udpClient.Close();
isUdpNull =
true
;
}
else
{
Console.WriteLine(
"IP:{0} 消息内容:"
+ Encoding.UTF8.GetString(buffer), tempEnd.Address.ToString());
}
}
}
catch
(Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
lock
(o)
{
if
(!isUdpNull)
{
udpClient.BeginReceive(
new
AsyncCallback(ReceiveCallback),
null
);
}
}
}
}
// 异步发送回调方法
static
void
SendCallback(IAsyncResult ar)
{
UdpClient tempUdpClient = (UdpClient)ar.AsyncState;
if
(tempUdpClient !=
null
)
{
Console.WriteLine(
"发送的字节数:{0}"
, tempUdpClient.EndSend(ar));
}
}
}
|