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

基于C#的UDP協(xié)議的同步通信實(shí)現(xiàn)代碼

 更新時(shí)間:2017年02月06日 11:19:42   作者:sunev  
本篇文章主要介紹了基于C#的UDP協(xié)議的同步實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、摘要

總結(jié)基于C#的UDP協(xié)議的同步通信。

 二、實(shí)驗(yàn)平臺(tái)

Visual Studio 2010

 三、實(shí)驗(yàn)原理

UDP傳輸協(xié)議同TCP傳輸協(xié)議的區(qū)別可查閱相關(guān)文檔,此處不再贅述。 

四、實(shí)例

4.1 采用socket實(shí)現(xiàn)UDP

由于UDP是一種無連接的協(xié)議。因此,為了使服務(wù)器應(yīng)用能夠發(fā)送和接收UDP數(shù)據(jù)包,則需要做兩件事情:

(1) 創(chuàng)建一個(gè)Socket對(duì)象;

(2) 將創(chuàng)建的套接字對(duì)象與本地IPEndPoint進(jìn)行綁定。

完成上述步驟后,那么創(chuàng)建的套接字就能夠在IPEndPoint上接收流入的UDP數(shù)據(jù)包,或者將流出的UDP數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中其他任意設(shè)備。使用UDP進(jìn)行通信時(shí),不需要連接。因?yàn)楫惖氐闹鳈C(jī)之間沒有建立連接,所以UDP不能使用標(biāo)準(zhǔn)的Send()和Receive()t套接字方法,而是使用兩個(gè)其他的方法:SendTo()和ReceiveFrom()。

SendTo()方法指定要發(fā)送的數(shù)據(jù),和目標(biāo)機(jī)器的IPEndPoint。該方法有多種不同的使用方法,可以根據(jù)具體的應(yīng)用進(jìn)行選擇,但是至少要指定數(shù)據(jù)包和目標(biāo)機(jī)器。如下:

SendTo(byte[] data,EndPoint Remote)

ReceiveFrom()方法同SendTo()方法類似,但是使用EndPoint對(duì)象聲明的方式不一樣。利用ref修飾,傳遞的不是一個(gè)EndPoint對(duì)象,而是將參數(shù)傳遞給一個(gè)EndPoint對(duì)象。

UDP應(yīng)用不是嚴(yán)格意義上的真正的服務(wù)器和客戶機(jī),而是平等的關(guān)系,即沒有主與次的關(guān)系。為了簡(jiǎn)便起見,仍然把下面的這個(gè)應(yīng)用叫做UDP服務(wù)器。

服務(wù)器端代碼:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDP
{
 class Program
 {
  static void Main(string[] args)
  {
   int recv;
   byte[] data = new byte[1024];

   //得到本機(jī)IP,設(shè)置TCP端口號(hào)   
   IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8001);
   Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   //綁定網(wǎng)絡(luò)地址
   newsock.Bind(ip);

   Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());

   //等待客戶機(jī)連接
   Console.WriteLine("Waiting for a client");

   //得到客戶機(jī)IP
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)(sender);
   recv = newsock.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));

   //客戶機(jī)連接成功后,發(fā)送信息
   string welcome = "你好 ! ";

   //字符串與字節(jié)數(shù)組相互轉(zhuǎn)換
   data = Encoding.ASCII.GetBytes(welcome);

   //發(fā)送信息
   newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
   while (true)
   {
    data = new byte[1024];
    //發(fā)送接收信息
    recv = newsock.ReceiveFrom(data, ref Remote);
    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    newsock.SendTo(data, recv, SocketFlags.None, Remote);
   }
  }

 }
}

對(duì)于接收流入的UDP服務(wù)器程序來說,必須將程序與本地系統(tǒng)中指定的UDP端口進(jìn)行綁定。這就可以通過使用合適的本地IP地址創(chuàng)建一個(gè)IPEndPoint對(duì)象,以及合適的UDP端口號(hào)。上述范例程序中的UDP服務(wù)器能夠在端口8001從網(wǎng)絡(luò)上接收任意流入的UDP數(shù)據(jù)包。

UDP客戶機(jī)程序與服務(wù)器程序非常類似。

因?yàn)榭蛻魴C(jī)不需要在指定的UDP端口等待流入的數(shù)據(jù),因此,不使用Bind()方法,而是使用在數(shù)據(jù)發(fā)送時(shí)系統(tǒng)隨機(jī)指定的一個(gè)UDP端口,而且使用同一個(gè)端口接收返回的消息。在開發(fā)產(chǎn)品時(shí),要為客戶機(jī)指定一套UDP端口,以便服務(wù)器和客戶機(jī)程序使用相同的端口號(hào)。UDP客戶機(jī)程序首先定義一個(gè)IPEndPoint,UDP服務(wù)器將發(fā)送數(shù)據(jù)包到這個(gè)IPEndPoint。如果在遠(yuǎn)程設(shè)備上運(yùn)行UDP服務(wù)器程序,在IPEndPoint定義中必須輸入適當(dāng)?shù)腎P地址和UDP端口號(hào)信息。

客戶端代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPClient
{
 class Program
 {
  static void Main(string[] args)
  {
   byte[] data = new byte[1024];
   string input, stringData;

   //構(gòu)建TCP 服務(wù)器
   Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

   //設(shè)置服務(wù)IP,設(shè)置TCP端口號(hào)
   IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);

   //定義網(wǎng)絡(luò)類型,數(shù)據(jù)連接類型和網(wǎng)絡(luò)協(xié)議UDP
   Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   string welcome = "你好! ";
   data = Encoding.ASCII.GetBytes(welcome);
   server.SendTo(data, data.Length, SocketFlags.None, ip);
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)sender;

   data = new byte[1024];
   //對(duì)于不存在的IP地址,加入此行代碼后,可以在指定時(shí)間內(nèi)解除阻塞模式限制
   int recv = server.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
   while (true)
   {
    input = Console.ReadLine();
    if (input == "exit")
     break;
    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
    data = new byte[1024];
    recv = server.ReceiveFrom(data, ref Remote);
    stringData = Encoding.ASCII.GetString(data, 0, recv);
    Console.WriteLine(stringData);
   }
   Console.WriteLine("Stopping Client.");
   server.Close();
  }

 }
}

上述代碼的實(shí)現(xiàn)邏輯為:相關(guān)設(shè)置完成后,服務(wù)器端先向客戶端發(fā)送信息,之后客戶端通過鍵盤發(fā)送字符串,服務(wù)器端收到后再發(fā)送給客戶端,如此循環(huán)。

4.2 采用UDPClient類實(shí)現(xiàn)

服務(wù)器端代碼:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Custom
{
 // 設(shè)置IP,IPV6
 private static readonly IPAddress GroupAddress = IPAddress.Parse("IP地址");
 // 設(shè)置端口
 private const int GroupPort = 11000;

 private static void StartListener()
 {
  bool done = false;

  UdpClient listener = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   //IPV6,組播
   listener.JoinMulticastGroup(GroupAddress);

   listener.Connect(groupEP);

   while (!done)
   {
    Console.WriteLine("Waiting for broadcast");

    byte[] bytes = listener.Receive(ref groupEP);

    Console.WriteLine("Received broadcast from {0} :\n {1}\n", groupEP.ToString(), Encoding.ASCII.GetString(bytes, 0, bytes.Length));
   }

   listener.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  StartListener();

  return 0;
 }
}

客戶端代碼:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Client
{

 private static IPAddress GroupAddress = IPAddress.Parse("IP地址");

 private static int GroupPort = 11000;

 private static void Send(String message)
 {
  UdpClient sender = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   Console.WriteLine("Sending datagram : {0}", message);

   byte[] bytes = Encoding.ASCII.GetBytes(message);

   sender.Send(bytes, bytes.Length, groupEP);

   sender.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  Send(args[0]);

  return 0;
 }
}

以上代碼需要說明的是:

(1) 上述代碼是基于IPV6地址的組播模式。IPv4中的廣播(broadcast)可以導(dǎo)致網(wǎng)絡(luò)性能的下降甚至廣播風(fēng)暴(broadcast storm)。在IPv6中就不存在廣播這一概念了,取而代之的是組播(multicast)和任意播(anycast)。

(2) IPV6地址表示方法:

a) X:X:X:X:X:X:X:X(每個(gè)X代表16位的16進(jìn)制數(shù)字),不區(qū)分大小寫;

b) 排頭的0可省略,比如09C0就可以寫成9C0,0000可以寫成0;

c) 連續(xù)為0的字段可以以::來代替,但是整個(gè)地址中::只能出現(xiàn)一次,比如FF01:0:0:0:0:0:0:1就可以簡(jiǎn)寫成FF01::1。

(3) 如果是采用窗體的形式建議使用這種格式,否則在接收數(shù)據(jù)時(shí)可能會(huì)出現(xiàn)死機(jī)的現(xiàn)象。

// 創(chuàng)建一個(gè)子線程

   Thread thread = new Thread(
    delegate()
    {
     try
     {
      //在這里寫你的代碼
     }
     catch (Exception )
     {

     }
    }
   );

   thread.Start();

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

相關(guān)文章

  • C#設(shè)計(jì)模式之Builder生成器模式解決帶老婆配置電腦問題實(shí)例

    C#設(shè)計(jì)模式之Builder生成器模式解決帶老婆配置電腦問題實(shí)例

    這篇文章主要介紹了C#設(shè)計(jì)模式之Builder生成器模式解決帶老婆配置電腦問題,簡(jiǎn)單介紹了生成器模式的概念、功能并結(jié)合具體實(shí)例形式分析了C#生成器模式解決配電腦問題的步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • c# Bitmap轉(zhuǎn)bitmapImage高效方法

    c# Bitmap轉(zhuǎn)bitmapImage高效方法

    本文主要介紹了c# Bitmap轉(zhuǎn)bitmapImage高效方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C#自定義控件指示燈效果

    C#自定義控件指示燈效果

    在C#中實(shí)現(xiàn)一個(gè)指示燈控件,可以通過GDI+技術(shù)繪制,首先使用Pen對(duì)象繪制外環(huán),然后用SolidBrush對(duì)象填充內(nèi)圓,通過RectangleF定義繪制和填充的邊界,控件的屬性包括顏色、間隙、外環(huán)寬度等,本文給大家介紹C#自定義控件指示燈效果,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • SQLite之C#版 System.Data.SQLite使用方法

    SQLite之C#版 System.Data.SQLite使用方法

    這篇文章主要介紹了SQLite之C#版 System.Data.SQLite使用方法,需要的朋友可以參考下
    2020-10-10
  • C#語(yǔ)言中字符類char的使用方法(總結(jié))

    C#語(yǔ)言中字符類char的使用方法(總結(jié))

    下面小編就為大家?guī)硪黄狢#語(yǔ)言中字符類char的使用方法(總結(jié))。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • Unity UGUI的ContentSizeFitter內(nèi)容尺寸適應(yīng)器組件使用示例

    Unity UGUI的ContentSizeFitter內(nèi)容尺寸適應(yīng)器組件使用示例

    這篇文章主要為大家介紹了Unity UGUI的ContentSizeFitter內(nèi)容尺寸適應(yīng)器組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • C#設(shè)置WinForm中DataGrid列的方法(列寬/列標(biāo)題等)

    C#設(shè)置WinForm中DataGrid列的方法(列寬/列標(biāo)題等)

    這篇文章主要介紹了C#設(shè)置WinForm中DataGrid列的方法,包括列寬、列標(biāo)題等部分,并分析了其中相關(guān)的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 最新評(píng)論

    拉萨市| 枞阳县| 海兴县| 依兰县| 秀山| 通辽市| 陕西省| 栾川县| 广安市| 改则县| 唐河县| 江口县| 盐池县| 吴忠市| 原平市| 嘉兴市| 盐山县| 东光县| 紫云| 西充县| 泌阳县| 镇江市| 乃东县| 岳阳县| 张家界市| 宝丰县| 洪湖市| 阿荣旗| 上犹县| 新田县| 长春市| 惠州市| 沁阳市| 甘泉县| 杭锦后旗| 平武县| 勐海县| 钟祥市| 南木林县| 怀宁县| 东城区|