国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#的Socket實(shí)現(xiàn)UDP協(xié)議通信示例代碼

2019-10-29 21:15:02
字體:
供稿:網(wǎng)友

今天稍花化了一點(diǎn)時(shí)間,利用C#的Socket驗(yàn)證了UDP的通信,為接下來特地利用UDP做個(gè)分布式的通信仿真系統(tǒng)打下基礎(chǔ)。眾所周知,UDP 就是用戶數(shù)據(jù)報(bào)協(xié)議,在互聯(lián)網(wǎng)參考模型的第四層——傳輸層。與TCP協(xié)議同層,都是提供信息的傳輸服務(wù),但與TCP最大區(qū)別就是,它是一種無連接不可靠的信息傳輸。

什么是無連接不可靠?直白點(diǎn)講就是,發(fā)送數(shù)據(jù)的時(shí)候,直接把UDP包往網(wǎng)絡(luò)一扔就完事了,接不接受收到發(fā)送的就不理了;接受數(shù)據(jù)的時(shí)候,有發(fā)給本地的UDP包就照單全收,收完再看是誰發(fā)的。相比TCP,少了握手建立連接,維護(hù)連接,連接釋放等一系列過程,因此具有很小的資源消耗和處理速度快的優(yōu)點(diǎn)。

好了說了一堆廢話,開始講怎么利用C#中Socket進(jìn)行UDP通信。TCP、UDP應(yīng)用程序可以通過TCPClient、TCPListener 和 UDPClient 類進(jìn)行編程,而這些協(xié)議類也建立在System.Net.Sockets.Socket 類的基礎(chǔ)上,并無需理會(huì)數(shù)據(jù)傳送的細(xì)節(jié)。但為了更好地理解Socket編程,這里還是利用了Socket類進(jìn)行UDP通信編程。

 UDP應(yīng)用上已經(jīng)無嚴(yán)格意義上的真正的服務(wù)器和客戶端之分了,端點(diǎn)之間都是平等的關(guān)系,因此進(jìn)行通信只需編寫一個(gè)程序即可。

下面給出關(guān)鍵部分代碼與說明:

關(guān)鍵的全局變量

private IPEndPoint ipLocalPoint; private EndPoint RemotePoint; private Socket mySocket; private bool RunningFlag = false; 

獲取本地IP的方法

private string getIPAddress()  {    // 獲得本機(jī)局域網(wǎng)IP地址    IPAddress[] AddressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;    if (AddressList.Length < 1)    {      return "";    }    return AddressList[0].ToString();  } 

IP與端口號(hào)有效驗(yàn)證

private int getValidPort(string port)   {     int lport;     //測(cè)試端口號(hào)是否有效     try     {       //是否為空       if (port == "")       {         throw new ArgumentException(           "端口號(hào)無效,不能啟動(dòng)DUP");       }       lport = System.Convert.ToInt32(port);     }     catch (Exception e)     {       //ArgumentException,        //FormatException,        //OverflowException       Console.WriteLine("無效的端口號(hào):" + e.ToString());       this.tbMsg.AppendText("無效的端口號(hào):" + e.ToString() + "/n");       return -1;     }     return lport;   }     private IPAddress getValidIP(string ip)   {     IPAddress lip = null;     //測(cè)試IP是否有效     try     {       //是否為空       if (!IPAddress.TryParse(ip, out lip))       {         throw new ArgumentException(           "IP無效,不能啟動(dòng)DUP");       }     }     catch (Exception e)     {       //ArgumentException,        //FormatException,        //OverflowException       Console.WriteLine("無效的IP:" + e.ToString());       this.tbMsg.AppendText("無效的IP:" + e.ToString() + "/n");       return null;     }     return lip;   } 

Socket的配置

//得到本機(jī)IP,設(shè)置UDP端口號(hào)   ip = getValidIP(tbLocalIP.Text); port = getValidPort(tbLocalPort.Text); ipLocalPoint = new IPEndPoint(ip, port);  //定義網(wǎng)絡(luò)類型,數(shù)據(jù)連接類型和網(wǎng)絡(luò)協(xié)議UDP mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //綁定網(wǎng)絡(luò)地址 mySocket.Bind(ipLocalPoint);  //得到客戶機(jī)IP ip = getValidIP(tbRemoteIP.Text); port = getValidPort(tbRemotePort.Text); IPEndPoint ipep = new IPEndPoint(ip, port); RemotePoint = (EndPoint)(ipep);  //啟動(dòng)一個(gè)新的線程,執(zhí)行方法this.ReceiveHandle, //以便在一個(gè)獨(dú)立的進(jìn)程中執(zhí)行數(shù)據(jù)接收的操作  RunningFlag = true; Thread thread = new Thread(new ThreadStart(this.ReceiveHandle)); thread.Start(); 

接收線程

//定義一個(gè)委托 public delegate void MyInvoke(string strRecv); private void ReceiveHandle() {   //接收數(shù)據(jù)處理線程   string msg;   byte[] data=new byte[1024];   MyInvoke myI = new MyInvoke(UpdateMsgTextBox);   while (RunningFlag)   {          if (mySocket == null || mySocket.Available < 1)     {       Thread.Sleep(200);       continue;     }     //跨線程調(diào)用控件      //接收UDP數(shù)據(jù)報(bào),引用參數(shù)RemotePoint獲得源地址      int rlen = mySocket.ReceiveFrom(data, ref RemotePoint);     msg = Encoding.Default.GetString(data, 0, rlen);     tbMsg.BeginInvoke(myI, new object[]{RemotePoint.ToString() + " : " + msg});        } } private void btSend_Click(object sender, EventArgs e) {   string msg;   msg = tbSendMsg.Text;   //發(fā)送UDP數(shù)據(jù)包   byte[] data = Encoding.Default.GetBytes(msg);   mySocket.SendTo(data, data.Length, SocketFlags.None, RemotePoint); } private void UpdateMsgTextBox(string msg) {   //接收數(shù)據(jù)顯示   this.tbMsg.AppendText( msg + "/n"); } 

以上只需設(shè)置好本地和遠(yuǎn)程的IP和端口號(hào),很容易就實(shí)現(xiàn)了UDP的雙向通信。雖說UDP數(shù)據(jù)包不能保證可靠傳輸,網(wǎng)絡(luò)繁忙、擁塞等因素,都有可能阻止數(shù)據(jù)包到達(dá)指定的目的地。但經(jīng)過測(cè)試,其通信還蠻可靠的,別忘了QQ也是利用UDP進(jìn)行即時(shí)通信的。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到c#教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 阳江市| 卢湾区| 汉中市| 双鸭山市| 兴仁县| 沈丘县| 南和县| 德昌县| 璧山县| 壤塘县| 兰州市| 清河县| 修水县| 施秉县| 石门县| 桑植县| 定州市| 中江县| 奉新县| 南和县| 崇左市| 红桥区| 纳雍县| 廊坊市| 和田市| 株洲县| 陇川县| 石泉县| 涞水县| 绥芬河市| 玉山县| 呼玛县| 红安县| 莱西市| 河北省| 平阳县| 读书| 长丰县| 锦屏县| 哈巴河县| 吴川市|