中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在C# 中使用Socke實現一個UDP

發布時間:2021-02-19 14:26:19 來源:億速云 閱讀:245 作者:Leah 欄目:開發技術

這篇文章給大家介紹在C# 中使用Socke實現一個UDP,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

一、概述

UDP和TCP是網絡通訊常用的兩個傳輸協議,C#一般可以通過Socket來實現UDP和TCP通訊,由于.NET框架通過UdpClient、TcpListener 、TcpClient這幾個類對Socket進行了封裝,使其使用更加方便, 本文就通過這幾個封裝過的類講解一下相關應用。

二、UDP基本應用

與TCP通信不同,UDP通信是不分服務端和客戶端的,通信雙方是對等的。為了描述方便,我們把通信雙方稱為發送方和接收方。

發送方:

首先創建一個UDP對象:

string locateIP = "127.0.0.1"; //本機IP

   int locatePort = 9001;   //發送端口

   IPAddress locateIpAddr = IPAddress.Parse(locateIP);

   IPEndPoint locatePoint = new IPEndPoint(locateIpAddr, locatePort);

   UdpClient udpClient = new UdpClient(locatePoint);

發送數據:

string remoteIP = "127.0.0.1";    //目標機器IP

   int remotePort = 9002;      //接收端口   

   IPAddress remoteIpAddr = IPAddress.Parse(remoteIP);

   IPEndPoint remotePoint = new IPEndPoint(remoteIpAddr, remotePort);

   byte[] buffer = Encoding.UTF8.GetBytes(“hello”);

   udpClient.Send(buffer, buffer.Length, remotePoint);

以上就完成了一個發送任務,一個較完整的發送代碼如下: 

public partial class FormServer : Form
 {
  private UdpClient udpClient = null;

  private void btnConnect_Click(object sender, EventArgs e)
  {
   string locateIP = "127.0.0.1";
   int locatePort = 9001;
   IPAddress locateIpAddr = IPAddress.Parse(locateIP);
   IPEndPoint locatePoint = new IPEndPoint(locateIpAddr, locatePort);
   udpClient = new UdpClient(locatePoint);

   this.groupWork.Enabled = true;
  }

  private void Send_Click(object sender, EventArgs e)
  {
   string text = this.txtSend.Text.Trim();
   string remoteIP = "127.0.0.1";
   int remotePort = 9002;
   byte[] buffer = Encoding.UTF8.GetBytes(text);

   if (udpClient != null)
   {
    IPAddress remoteIp = IPAddress.Parse(remoteIP);
    IPEndPoint remotePoint = new IPEndPoint(remoteIp, remotePort);
    udpClient.Send(buffer, buffer.Length, remotePoint);
   }

   Debug.WriteLine("Send OK");
  }
 }

接收端: 

首先創建一個UDP對象:

string locateIP = "127.0.0.1";

   int locatePort = 9002;

   IPAddress locateIpAddr = IPAddress.Parse(locateIP);

   IPEndPoint locatePoint = new IPEndPoint(locateIpAddr, locatePort);

   UdpClient udpClient = new UdpClient(locatePoint);

接收數據: 

IPEndPoint remotePoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 1);

  var received = udpClient.Receive(ref remotePoint);

  string info = Encoding.UTF8.GetString(received);

  string from=$” {remotePoint.Address}:{remotePoint.Port}”;

注意兩點:

1、remotePoint是獲得發送方的IP信息,定義時可以輸入任何合法的IP和端口信息;

2、Receive方法是阻塞方法,所以需要在新的線程內運行,程序會一直等待接收數據,當接收到一包數據時程序就返回,要持續接收數據需要重復調用Receive方法。

一個較完整的接收端代碼如下: 

public partial class FormClent : Form
 {
  private UdpClient udpClient = null; 

  private void btnConnect_Click(object sender, EventArgs e)
  {
   string locateIP = "127.0.0.1";
   int locatePort = 9002;
   IPAddress locateIpAddr = IPAddress.Parse(locateIP);
   IPEndPoint locatePoint = new IPEndPoint(locateIpAddr, locatePort);
   udpClient = new UdpClient(locatePoint);
   IPEndPoint remotePoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 1);

   Task.Run(() =>
   {
    while (true)
    {
     if (udpClient != null)
     {
      var received = udpClient.Receive(ref remotePoint);
      string info = Encoding.UTF8.GetString(received);
      string from=$” {remotePoint.Address}:{remotePoint.Port}”; 
     }
    }
   }); 
  }
 }

三、丟包和亂序問題

   當發送端發送一包數據時,不管對方是否接收都是發送成功的,UDP協議本身并不會對發送的可靠性進行驗證。(這里的可靠性是指是否接收到,如果對方接收到數據包,其內容還是可靠的,這個在鏈路層進行了保證。)同時,由于網絡延時等因素,先發送的包并不能確定先被接收到,所以由于這兩個原因,UDP通信存在丟包和亂序的情況。

   某些業務場景下,比如實時狀態監控,可能對丟包和亂序情況并不敏感, 可以不用處理,但大部分情況下還是介意丟包的,簡單的處理辦法就是把包的頭部固定長度的空間拿出來存放核對信息,比如包編號,如果有缺失,可以要求發送方重發,也可以進行排序。

四、將數據接收包裝為事件

 我們對UdpClent又進行一次封裝,啟用一個線程進行接收數據,將接收到的數據包通過事件發布出來,這樣使用起來就更方便了。

namespace Communication.UDPClient
{
 public class UdpStateEventArgs : EventArgs
 {  
  public IPEndPoint remoteEndPoint;  
  public byte[] buffer = null;
 }

 public delegate void UDPReceivedEventHandler(UdpStateEventArgs args);

 public class UDPClient
 {
  private UdpClient udpClient;
  public event UDPReceivedEventHandler UDPMessageReceived;

  public UDPClient(string locateIP, int locatePort)
  {
   IPAddress locateIp = IPAddress.Parse(locateIP);
   IPEndPoint locatePoint = new IPEndPoint(locateIp, locatePort);
   udpClient = new UdpClient(locatePoint);

   //監聽創建好后,創建一個線程,開始接收信息
   Task.Run(() =>
   {
    while (true)
    {
     UdpStateEventArgs udpReceiveState = new UdpStateEventArgs();

     if (udpClient != null)
     {
      IPEndPoint remotePoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 1);
      var received = udpClient.Receive(ref remotePoint);
      udpReceiveState.remoteEndPoint = remotePoint;
      udpReceiveState.buffer = received;
      UDPMessageReceived?.Invoke(udpReceiveState);
     }
     else
     {
      break;
     }
    }
   });
  }
 }
}

具體使用辦法:

private void btnConnect_Click(object sender, EventArgs e)
  {
   string locateIP = "127.0.0.1";
   int locatePort = 9002;   
   UDPClient udpClient = new UDPClient(locateIP, locatePort);
   udpClient.UDPMessageReceived += UdpClient_UDPMessageReceived;   
  }

  private void UdpClient_UDPMessageReceived(UdpStateEventArgs args)
  {
   var remotePoint = args.remoteEndPoint;
   string info = Encoding.UTF8.GetString(args.buffer); 
  }

關于在C# 中使用Socke實現一個UDP就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

udp
AI

澄江县| 汽车| 万源市| 闵行区| 通海县| 积石山| 永新县| 枣庄市| 化德县| 简阳市| 开封县| 萍乡市| 区。| 青田县| 买车| 郸城县| 湾仔区| 内乡县| 象州县| 青神县| 若尔盖县| 星座| 隆德县| 中西区| 筠连县| 濮阳县| 灌阳县| 兰溪市| 恭城| 梓潼县| 汶上县| 安远县| 庆元县| 五峰| 巨野县| 尼勒克县| 盐池县| 南川市| 株洲县| 喀喇沁旗| 德阳市|