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();
}
///
/// 用于UDP发送的网络服务类
///
private
UdpClient udpcSend;
///
/// 用于UDP接收的网络服务类
///
private
UdpClient udpcRecv;
///
/// 按钮:发送数据
///
///
///
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);
}
///
/// 发送信息
///
///
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);
}
///
/// 开关:在监听UDP报文阶段为true,否则为false
///
bool
IsUdpcRecvStart =
false
;
///
/// 线程:不断监听UDP报文
///
Thread thrRecv;
///
/// 按钮:接收数据开关
///
///
///
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监听器已成功关闭"
);
}
}
///
/// 接收数据
///
///
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 =
""
;
}
}
///
/// 关闭程序,强制退出
///
///
///
private
void
FormMain_FormClosing(
object
sender, FormClosingEventArgs e)
{
Environment.Exit(0);
}
}
}
|
4.其他
在关闭UdpClient(调用它的Close函数)前,一定要先关闭监听UDP的线程,否则会报错:“一个封锁操作被对 WSACancelBlockingCall 的调用中断”。
END