异步关闭UdpClient

不知道大家有没有遇见,UdpClient在监听的时候,不管同步还是异步的,调用Close()方法或者调用线程的Abort()方法,会抛出一个异常或者出现一个正在终止线程的小窗体,我理解是UdpClient正在等待接收,线程阻塞了,所以不能强制关闭Udp连接,这个问题我在网上找了好久都没有找到好的解决方法,当时为了不让弹出那个正在终止线程的小框框,我用System.Environment.Exit(0)方法勉强的实现了,最近我自己想出了一个解决的方法,因为Udp连接正在等待接收呢,只要让Udp连接接收到数据,这时就可以正常的Close()了,这样关闭Udp连接的时候不会出现任何异常,下面是我的代码:
C# code
?
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));
             }
         }
     }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 WinForms 中实现 UDP 数据收发可以通过创建和使用 `UdpClient` 类来完成。下面是一个简单的示例代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Windows.Forms; public partial class MainForm : Form { private UdpClient udpClient; private IPEndPoint remoteEndPoint; public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { // 初始化 UdpClient 和远程端点 udpClient = new UdpClient(); remoteEndPoint = new IPEndPoint(IPAddress.Parse("远程IP地址"), 远程端口号); } private void btnSend_Click(object sender, EventArgs e) { string message = txtMessage.Text; // 将消息转换为字节数组 byte[] sendData = Encoding.UTF8.GetBytes(message); // 发送数据 udpClient.Send(sendData, sendData.Length, remoteEndPoint); // 清空文本框 txtMessage.Text = ""; } private void btnReceive_Click(object sender, EventArgs e) { // 开始异步接收数据 udpClient.BeginReceive(ReceiveCallback, null); } private void ReceiveCallback(IAsyncResult result) { // 结束异步接收并获取接收的数据和远程端点 byte[] receivedData = udpClient.EndReceive(result, ref remoteEndPoint); // 将接收到的字节数组转换为字符串 string receivedMessage = Encoding.UTF8.GetString(receivedData); // 在 UI 线程更新 UI 控件 Invoke(new Action(() => { // 在文本框中显示接收到的消息 txtReceived.Text = receivedMessage; })); // 继续异步接收数据 udpClient.BeginReceive(ReceiveCallback, null); } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { // 关闭 UdpClient udpClient.Close(); } } ``` 上述代码中,我们创建了一个 `UdpClient` 实例和一个 `IPEndPoint` 实例来表示远程端点。`btnSend_Click` 事件处理程序用于发送文本框中的消息,`btnReceive_Click` 事件处理程序用于开始异步接收数据。`ReceiveCallback` 方法是接收完成时的回调方法,它将接收到的消息显示在文本框中。 确保将 "远程IP地址" 和 "远程端口号" 替换为实际的远程 IP 地址和端口号。 在 `MainForm_Load` 中初始化 `UdpClient` 和远程端点,在 `MainForm_FormClosing` 中关闭 `UdpClient`,以确保在关闭窗体时释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值