首頁 >後端開發 >C#.Net教程 >C#的Socket實作UDP協定通訊的範例程式碼詳解

C#的Socket實作UDP協定通訊的範例程式碼詳解

黄舟
黄舟原創
2017-03-23 11:57:013006瀏覽

本篇文章主要介紹了C#的Socket實作UDP協定通訊範例程式碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

今天稍花化了一點時間,利用C#的Socket驗證了UDP的通信,為接下來特地利用UDP做個分佈式的通信模擬系統打下基礎。眾所周知,UDP 是用戶資料報協議,在網路參考模型的第四層-傳輸層。與TCP協定同層,都是提供資訊的傳輸服務,但與TCP最大差別就是,它是一種無連線不可靠的資訊傳輸。

什麼是無連線不可靠?直白點講就是,發送資料的時候,直接把UDP包往網路一丟就完事了,接不接受收到發送的就不理了;接受資料的時候,有發給本地的UDP包就照單全收,收完再看是誰發的。相比TCP,少了握手建立連接,維護連接,連接釋放等一系列過程,因此具有很小的資源消耗和處理速度快的優點。

好了說了一堆廢話,開始講怎麼利用C#中Socket進行UDP通訊。 TCP、UDP應用程式可以透過TCPClient、TCPListener 和 UDPClient 類別進行程式設計,而這些協定類別也建立在System.Net.Sockets.Socket 類別的基礎上,而無需理會資料傳送的細節。但為了更能理解Socket編程,這裡還是利用了Socket類別進行UDP通訊編程。

 UDP應用程式上已經無嚴格意義上的真正的伺服器和客戶端之分了,端點之間都是平等的關係,因此進行通訊只需編寫一個程式即可。

下面給出關鍵部分程式碼與說明:

關鍵的全域變數

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

取得本機IP的方法

private string getIPAddress() 
 { 
   // 获得本机局域网IP地址 
   IPAddress[] AddressList = Dns.GetHostByName(Dns.GetHostName()).AddressList; 
   if (AddressList.Length < 1) 
   { 
     return ""; 
   } 
   return AddressList[0].ToString(); 
 }

IP與連接埠號碼有效驗證

private int getValidPort(string port) 
  { 
    int lport; 
    //测试端口号是否有效 
    try 
    { 
      //是否为空 
      if (port == "") 
      { 
        throw new ArgumentException( 
          "端口号无效,不能启动DUP"); 
      } 
      lport = System.Convert.ToInt32(port); 
    } 
    catch (Exception e) 
    { 
      //ArgumentException,  
      //FormatException,  
      //OverflowException 
      Console.WriteLine("无效的端口号:" + e.ToString()); 
      this.tbMsg.AppendText("无效的端口号:" + e.ToString() + "\n"); 
      return -1; 
    } 
    return lport; 
  } 
 
 
  private IPAddress getValidIP(string ip) 
  { 
    IPAddress lip = null; 
    //测试IP是否有效 
    try 
    { 
      //是否为空 
      if (!IPAddress.TryParse(ip, out lip)) 
      { 
        throw new ArgumentException( 
          "IP无效,不能启动DUP"); 
      } 
    } 
    catch (Exception e) 
    { 
      //ArgumentException,  
      //FormatException,  
      //OverflowException 
      Console.WriteLine("无效的IP:" + e.ToString()); 
      this.tbMsg.AppendText("无效的IP:" + e.ToString() + "\n"); 
      return null; 
    } 
    return lip; 
  }

Socket的設定

//得到本机IP,设置UDP端口号   
ip = getValidIP(tbLocalIP.Text); 
port = getValidPort(tbLocalPort.Text); 
ipLocalPoint = new IPEndPoint(ip, port); 
 
//定义网络类型,数据连接类型和网络协议UDP 
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
 
//绑定网络地址 
mySocket.Bind(ipLocalPoint); 
 
//得到客户机IP 
ip = getValidIP(tbRemoteIP.Text); 
port = getValidPort(tbRemotePort.Text); 
IPEndPoint ipep = new IPEndPoint(ip, port); 
RemotePoint = (EndPoint)(ipep); 
 
//启动一个新的线程,执行方法this.ReceiveHandle, 
//以便在一个独立的进程中执行数据接收的操作 
 
RunningFlag = true; 
Thread thread = new Thread(new ThreadStart(this.ReceiveHandle)); 
thread.Start();

接收執行緒

//定义一个委托 
public delegate void MyInvoke(string strRecv); 
private void ReceiveHandle() 
{ 
  //接收数据处理线程 
  string msg; 
  byte[] data=new byte[1024]; 
  MyInvoke myI = new MyInvoke(UpdateMsgTextBox); 
  while (RunningFlag) 
  { 
     
    if (mySocket == null || mySocket.Available < 1) 
    { 
      Thread.Sleep(200); 
      continue; 
    } 
    //跨线程调用控件 
     //接收UDP数据报,引用参数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; 
  //发送UDP数据包 
  byte[] data = Encoding.Default.GetBytes(msg); 
  mySocket.SendTo(data, data.Length, SocketFlags.None, RemotePoint); 
} 
private void UpdateMsgTextBox(string msg) 
{ 
  //接收数据显示 
  this.tbMsg.AppendText( msg + "\n"); 
}

以上只需設定好本地和遠端的IP和連接埠號,很容易就實作了UDP的雙向通訊。雖說UDP封包無法保證可靠傳輸,網路繁忙、擁塞等因素,都有可能阻止封包到達指定的目的地。但經過測試,其通訊還蠻可靠的,別忘了QQ也是利用UDP進行即時通訊的。


#

以上是C#的Socket實作UDP協定通訊的範例程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn