C# UDP編程(通過類UdpClient實現收發)

jopen 9年前發布 | 39K 次閱讀 UDP 網絡技術

1.程序說明

今天學了C#的UDP,實現了一個非常簡單的UDP收發工具

C# UDP編程(通過類UdpClient實現收發)

這個工具的功能就是發送UDP報文和監聽UDP報文。在左側的文本框中輸入文字,單擊“發送數據”按鈕發送UDP報文。如果這個時候點擊了右邊的“接收數據”按鈕,右邊的文本框會顯示左邊發送的數據。右側的按鈕,按一次開始監聽,按第二次終止監聽。

2.控件布局

程序的控件布局如下圖

C# UDP編程(通過類UdpClient實現收發)

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
 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!