C# UDP編程(通過類UdpClient實現收發)
1.程序說明
今天學了C#的UDP,實現了一個非常簡單的UDP收發工具
這個工具的功能就是發送UDP報文和監聽UDP報文。在左側的文本框中輸入文字,單擊“發送數據”按鈕發送UDP報文。如果這個時候點擊了右邊的“接收數據”按鈕,右邊的文本框會顯示左邊發送的數據。右側的按鈕,按一次開始監聽,按第二次終止監聽。
2.控件布局
程序的控件布局如下圖
3.程序代碼
程序的C#代碼如下:
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); } } }</pre>
4.其他
在關閉UdpClient(調用它的Close函數)前,一定要先關閉監聽UDP的線程,否則會報錯:“一個封鎖操作被對 WSACancelBlockingCall 的調用中斷”。
END
來自:http://my.oschina.net/Tsybius2014/blog/351974