C# UDP编程(通过类UdpClient实现收发)

1.程序说明

今天学了C#的UDP,实现了一个非常简单的UDP收发工具


这个工具的功能就是发送UDP报文和监听UDP报文。在左侧的文本框中输入文字,单击“发送数据”按钮发送UDP报文。如果这个时候点击了右边的“接收数据”按钮,右边的文本框会显示左边发送的数据。右侧的按钮,按一次开始监听,按第二次终止监听。

2.控件布局

程序的控件布局如下图

3.程序代码

程序的C#代码如下:

?
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Threading.Tasks;
using  System.Windows.Forms;
 
//本段代码中需要新增加的命名空间
using  System.Net.Sockets;
using  System.Net;
using  System.Threading;
 
namespace  UDPTest
{
     public  partial  class  FormMain : Form
     {
         public  FormMain()
         {
             InitializeComponent();
         }
 
         /// <summary>
         /// 用于UDP发送的网络服务类
         /// </summary>
         private  UdpClient udpcSend;
         /// <summary>
         /// 用于UDP接收的网络服务类
         /// </summary>
         private  UdpClient udpcRecv;
 
         /// <summary>
         /// 按钮:发送数据
         /// </summary>
         /// <param name="sender"></param>
         /// <param name="e"></param>
         private  void  btnSend_Click( object  sender, EventArgs e)
         {
             if  ( string .IsNullOrWhiteSpace(txtSendMssg.Text))
             {
                 MessageBox.Show( "请先输入待发送内容" );
                 return ;
             }
 
             // 匿名发送
             //udpcSend = new UdpClient(0);             // 自动分配本地IPv4地址
 
             // 实名发送
             IPEndPoint localIpep =  new  IPEndPoint(
                 IPAddress.Parse( "127.0.0.1" ), 12345);  // 本机IP,指定的端口号
             udpcSend =  new  UdpClient(localIpep);
 
             Thread thrSend =  new  Thread(SendMessage);
             thrSend.Start(txtSendMssg.Text);
         }
 
         /// <summary>
         /// 发送信息
         /// </summary>
         /// <param name="obj"></param>
         private  void  SendMessage( object  obj)
         {
             string  message = ( string )obj;
             byte [] sendbytes = Encoding.Unicode.GetBytes(message);
 
             IPEndPoint remoteIpep =  new  IPEndPoint(
                 IPAddress.Parse( "127.0.0.1" ), 8848);  // 发送到的IP地址和端口号
 
             udpcSend.Send(sendbytes, sendbytes.Length, remoteIpep);
             udpcSend.Close();
 
             ResetTextBox(txtSendMssg);
         }
 
         /// <summary>
         /// 开关:在监听UDP报文阶段为true,否则为false
         /// </summary>
         bool  IsUdpcRecvStart =  false ;
         /// <summary>
         /// 线程:不断监听UDP报文
         /// </summary>
         Thread thrRecv;
 
         /// <summary>
         /// 按钮:接收数据开关
         /// </summary>
         /// <param name="sender"></param>
         /// <param name="e"></param>
         private  void  btnRecv_Click( object  sender, EventArgs e)
         {
             if  (!IsUdpcRecvStart)  // 未监听的情况,开始监听
             {
                 IPEndPoint localIpep =  new  IPEndPoint(
                     IPAddress.Parse( "127.0.0.1" ), 8848);  // 本机IP和监听端口号
 
                 udpcRecv =  new  UdpClient(localIpep);
 
                 thrRecv =  new  Thread(ReceiveMessage);
                 thrRecv.Start();
 
                 IsUdpcRecvStart =  true ;
                 ShowMessage(txtRecvMssg,  "UDP监听器已成功启动" );
             }
             else                   // 正在监听的情况,终止监听
             {
                 thrRecv.Abort();  // 必须先关闭这个线程,否则会异常
                 udpcRecv.Close();
 
                 IsUdpcRecvStart =  false ;
                 ShowMessage(txtRecvMssg,  "UDP监听器已成功关闭" );
             }
         }
 
         /// <summary>
         /// 接收数据
         /// </summary>
         /// <param name="obj"></param>
         private  void  ReceiveMessage( object  obj)
         {
             IPEndPoint remoteIpep =  new  IPEndPoint(IPAddress.Any, 0);
             while  ( true )
             {
                 try
                 {
                     byte [] bytRecv = udpcRecv.Receive( ref  remoteIpep);
                     string  message = Encoding.Unicode.GetString(
                         bytRecv, 0, bytRecv.Length);
 
                     ShowMessage(txtRecvMssg, 
                         string .Format( "{0}[{1}]" , remoteIpep, message));
                 }
                 catch  (Exception ex)
                 {
                     ShowMessage(txtRecvMssg, ex.Message);
                     break ;
                 }
             }
         }
 
         // 向TextBox中添加文本
         delegate  void  ShowMessageDelegate(TextBox txtbox,  string  message);
         private  void  ShowMessage(TextBox txtbox,  string  message)
         {
             if  (txtbox.InvokeRequired)
             {
                 ShowMessageDelegate showMessageDelegate = ShowMessage;
                 txtbox.Invoke(showMessageDelegate,  new  object [] { txtbox, message });
             }
             else
             {
                 txtbox.Text += message +  "\r\n" ;
             }
         }
 
         // 清空指定TextBox中的文本
         delegate  void  ResetTextBoxDelegate(TextBox txtbox);
         private  void  ResetTextBox(TextBox txtbox)
         {
             if  (txtbox.InvokeRequired)
             {
                 ResetTextBoxDelegate resetTextBoxDelegate = ResetTextBox;
                 txtbox.Invoke(resetTextBoxDelegate,  new  object [] { txtbox });
             }
             else
             {
                 txtbox.Text =  "" ;
             }
         }
 
         /// <summary>
         /// 关闭程序,强制退出
         /// </summary>
         /// <param name="sender"></param>
         /// <param name="e"></param>
         private  void  FormMain_FormClosing( object  sender, FormClosingEventArgs e)
         {
             Environment.Exit(0);
         }
     }
}

4.其他

在关闭UdpClient(调用它的Close函数)前,一定要先关闭监听UDP的线程,否则会报错:“一个封锁操作被对 WSACancelBlockingCall 的调用中断”。

END

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值