最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# 網(wǎng)絡(luò)編程之UDP

 更新時(shí)間:2021年02月19日 10:46:39   作者:seabluescn  
這篇文章主要介紹了C# 網(wǎng)絡(luò)編程之UDP的相關(guān)資料,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下

一、概述

UDP和TCP是網(wǎng)絡(luò)通訊常用的兩個(gè)傳輸協(xié)議,C#一般可以通過Socket來實(shí)現(xiàn)UDP和TCP通訊,由于.NET框架通過UdpClient、TcpListener 、TcpClient這幾個(gè)類對(duì)Socket進(jìn)行了封裝,使其使用更加方便, 本文就通過這幾個(gè)封裝過的類講解一下相關(guān)應(yīng)用。

二、UDP基本應(yīng)用

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

發(fā)送方:

首先創(chuàng)建一個(gè)UDP對(duì)象:

string locateIP = "127.0.0.1"; //本機(jī)IP

   int locatePort = 9001;   //發(fā)送端口

   IPAddress locateIpAddr = IPAddress.Parse(locateIP);

   IPEndPoint locatePoint = new IPEndPoint(locateIpAddr, locatePort);

   UdpClient udpClient = new UdpClient(locatePoint);

發(fā)送數(shù)據(jù):

string remoteIP = "127.0.0.1";    //目標(biāo)機(jī)器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);

以上就完成了一個(gè)發(fā)送任務(wù),一個(gè)較完整的發(fā)送代碼如下: 

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");
  }
 }

接收端: 

首先創(chuàng)建一個(gè)UDP對(duì)象:

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);

接收數(shù)據(jù): 

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}”;

注意兩點(diǎn):

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

2、Receive方法是阻塞方法,所以需要在新的線程內(nèi)運(yùn)行,程序會(huì)一直等待接收數(shù)據(jù),當(dāng)接收到一包數(shù)據(jù)時(shí)程序就返回,要持續(xù)接收數(shù)據(jù)需要重復(fù)調(diào)用Receive方法。

一個(gè)較完整的接收端代碼如下: 

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}”; 
     }
    }
   }); 
  }
 }

三、丟包和亂序問題

   當(dāng)發(fā)送端發(fā)送一包數(shù)據(jù)時(shí),不管對(duì)方是否接收都是發(fā)送成功的,UDP協(xié)議本身并不會(huì)對(duì)發(fā)送的可靠性進(jìn)行驗(yàn)證。(這里的可靠性是指是否接收到,如果對(duì)方接收到數(shù)據(jù)包,其內(nèi)容還是可靠的,這個(gè)在鏈路層進(jìn)行了保證。)同時(shí),由于網(wǎng)絡(luò)延時(shí)等因素,先發(fā)送的包并不能確定先被接收到,所以由于這兩個(gè)原因,UDP通信存在丟包和亂序的情況。

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

四、將數(shù)據(jù)接收包裝為事件

 我們對(duì)UdpClent又進(jìn)行一次封裝,啟用一個(gè)線程進(jìn)行接收數(shù)據(jù),將接收到的數(shù)據(jù)包通過事件發(fā)布出來,這樣使用起來就更方便了。

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);

   //監(jiān)聽創(chuàng)建好后,創(chuàng)建一個(gè)線程,開始接收信息
   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#網(wǎng)絡(luò)編程入門系列包括三篇文章:

(一)C#網(wǎng)絡(luò)編程入門之UDP

(二)C#網(wǎng)絡(luò)編程入門之TCP

(三)C#網(wǎng)絡(luò)編程入門之HTTP

以上就是C# 網(wǎng)絡(luò)編程之UDP的詳細(xì)內(nèi)容,更多關(guān)于C# 網(wǎng)絡(luò)編程UDP的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 輕松學(xué)習(xí)C#的讀寫操作

    輕松學(xué)習(xí)C#的讀寫操作

    輕松學(xué)習(xí)C#的讀寫操作,小編也是第一次接觸C#的讀寫操作,感興趣的小伙伴們可以參考一下,大家一起學(xué)習(xí)
    2015-11-11
  • c#?Task.Wait()與awaiat?Task異常處理的區(qū)別說明

    c#?Task.Wait()與awaiat?Task異常處理的區(qū)別說明

    這篇文章主要介紹了c#?Task.Wait()與awaiat?Task異常處理的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • C#繪制曲線圖的方法

    C#繪制曲線圖的方法

    這篇文章主要介紹了C#繪制曲線圖的方法,以完整實(shí)例形式較為詳細(xì)的分析了C#進(jìn)行曲線繪制的具體步驟與相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • C#中使用JSON.NET實(shí)現(xiàn)JSON、XML相互轉(zhuǎn)換

    C#中使用JSON.NET實(shí)現(xiàn)JSON、XML相互轉(zhuǎn)換

    這篇文章主要介紹了C#中使用JSON.NET實(shí)現(xiàn)JSON、XML相互轉(zhuǎn)換的相關(guān)代碼及示例,需要的朋友可以參考下
    2015-11-11
  • C#基于共享內(nèi)存實(shí)現(xiàn)跨進(jìn)程隊(duì)列

    C#基于共享內(nèi)存實(shí)現(xiàn)跨進(jìn)程隊(duì)列

    進(jìn)程通信一般情況下比較少用,但是也有一些使用場景,有些做視頻傳輸?shù)乃坪鯐?huì)用多進(jìn)程來實(shí)現(xiàn),還有在子進(jìn)程中調(diào)用特定的庫來避免內(nèi)存泄漏,筆者最近也遇到了需要使用多進(jìn)程的場景,本文介紹了C#基于共享內(nèi)存實(shí)現(xiàn)跨進(jìn)程隊(duì)列,需要的朋友可以參考下
    2024-07-07
  • C#簡單的向量用法實(shí)例教程

    C#簡單的向量用法實(shí)例教程

    這篇文章主要介紹了C#簡單的向量用法,需要的朋友可以參考下
    2014-07-07
  • c#使用EPPlus封裝excel表格導(dǎo)入功能的問題

    c#使用EPPlus封裝excel表格導(dǎo)入功能的問題

    這篇文章主要介紹了c#使用EPPlus封裝excel表格導(dǎo)入功能的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C# 批處理調(diào)用方法

    C# 批處理調(diào)用方法

    當(dāng)批處理和aspx不在同一目錄中時(shí),最好用WorkingDirectory設(shè)置啟動(dòng)的進(jìn)程的初始目錄為批處理所在目錄,否則如上例中批處理新建的目錄就應(yīng)在aspx所在目錄中而不是批處理所在目錄了!
    2008-12-12
  • C#中的Task.WhenAll和Task.WhenAny方法介紹

    C#中的Task.WhenAll和Task.WhenAny方法介紹

    這篇文章介紹了C#中的Task.WhenAll和Task.WhenAny方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#中Write()和WriteLine()的區(qū)別分析

    C#中Write()和WriteLine()的區(qū)別分析

    這篇文章主要介紹了C#中Write()和WriteLine()的區(qū)別分析,需要的朋友可以參考下
    2020-11-11

最新評(píng)論

刚察县| 宁德市| 娄底市| 汉源县| 仁怀市| 青神县| 岐山县| 剑阁县| 大邑县| 太康县| 兴安县| 大丰市| 文安县| 墨竹工卡县| 上犹县| 武乡县| 儋州市| 交口县| 易门县| 宁国市| 古浪县| 泰来县| 龙陵县| 南乐县| 福贡县| 双辽市| 宣恩县| 宁武县| 临沂市| 固安县| 莱州市| 册亨县| 阿拉善盟| 平乐县| 同仁县| 庆安县| 吴川市| 佛坪县| 沧州市| 通辽市| 宿松县|