1. 程式人生 > >基於C#的UDP協議的異步實現

基於C#的UDP協議的異步實現

connect sleep ack bind 服務器 endpoint length ddr blog

一、摘要

  總結UDP傳輸協議的異步實現。

二、實驗平臺

  visual studio 2010

三、實驗實例

  服務器端代碼:

技術分享
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace AsyncServer
{
    // 定義 UdpState類
    public class UdpState
    {
        
public UdpClient udpClient; public IPEndPoint ipEndPoint; public const int BufferSize = 1024; public byte[] buffer = new byte[BufferSize]; public int counter = 0; } // 異步UDP類 public class AsyncUdpSever { // 定義節點 private IPEndPoint ipEndPoint = null
; private IPEndPoint remoteEP = null; // 定義UDP發送和接收 private UdpClient udpReceive = null; private UdpClient udpSend = null; // 定義端口 private const int listenPort = 1100; private const int remotePort = 1101; UdpState udpReceiveState = null
; UdpState udpSendState = null; // 異步狀態同步 private ManualResetEvent sendDone = new ManualResetEvent(false); private ManualResetEvent receiveDone = new ManualResetEvent(false); public AsyncUdpSever() { // 本機節點 ipEndPoint = new IPEndPoint(IPAddress.Any, listenPort); // 遠程節點 remoteEP = new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], remotePort); // 實例化 udpReceive = new UdpClient(ipEndPoint); udpSend = new UdpClient(); // 分別實例化udpSendState、udpReceiveState udpReceiveState = new UdpState(); udpReceiveState.udpClient = udpReceive; udpReceiveState.ipEndPoint = ipEndPoint; udpSendState = new UdpState(); udpSendState.udpClient = udpSend; udpSendState.ipEndPoint = remoteEP; } public void ReceiveMsg() { Console.WriteLine("listening for messages"); while (true) { lock (this) { // 調用接收回調函數 IAsyncResult iar = udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState); receiveDone.WaitOne(); Thread.Sleep(100); } } } // 接收回調函數 private void ReceiveCallback(IAsyncResult iar) { UdpState udpReceiveState = iar.AsyncState as UdpState; if (iar.IsCompleted) { Byte[] receiveBytes = udpReceiveState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint); string receiveString = Encoding.ASCII.GetString(receiveBytes); Console.WriteLine("Received: {0}", receiveString); //Thread.Sleep(100); receiveDone.Set(); SendMsg(); } } // 發送函數 private void SendMsg() { udpSend.Connect(udpSendState.ipEndPoint); udpSendState.udpClient = udpSend; udpSendState.counter++; string message = string.Format("第{0}個UDP請求處理完成!", udpSendState.counter); Byte[] sendBytes = Encoding.Unicode.GetBytes(message); udpSend.BeginSend(sendBytes, sendBytes.Length, new AsyncCallback(SendCallback), udpSendState); sendDone.WaitOne(); } // 發送回調函數 private void SendCallback(IAsyncResult iar) { UdpState udpState = iar.AsyncState as UdpState; Console.WriteLine("第{0}個請求處理完畢!", udpState.counter); Console.WriteLine("number of bytes sent: {0}", udpState.udpClient.EndSend(iar)); sendDone.Set(); } // 主函數 public static void Main() { AsyncUdpSever aus = new AsyncUdpSever(); Thread t = new Thread(new ThreadStart(aus.ReceiveMsg)); t.Start(); Console.Read(); } } }
技術分享

  客戶端代碼:

技術分享
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace AsyncClient
{
    // 定義 UdpState類
    public class UdpState
    {
        public UdpClient udpClient = null;
        public IPEndPoint ipEndPoint = null;
        public const int BufferSize = 1024;
        public byte[] buffer = new byte[BufferSize];
        public int counter = 0;
    }
    // 異步UDP類
    public class AsyncUdpClient
    {
        public static bool messageSent = false;
        // Receive a message and write it to the console.
        // 定義端口
        private const int listenPort = 1101;
        private const int remotePort = 1100;
        // 定義節點
        private IPEndPoint localEP = null;
        private IPEndPoint remoteEP = null;
        // 定義UDP發送和接收
        private UdpClient udpReceive = null;
        private UdpClient udpSend = null;
        private UdpState udpSendState = null;
        private UdpState udpReceiveState = null;
        private int counter = 0;
        // 異步狀態同步
        private ManualResetEvent sendDone = new ManualResetEvent(false);
        private ManualResetEvent receiveDone = new ManualResetEvent(false);
        // 定義套接字
        //private Socket receiveSocket;
        //private Socket sendSocket;

        public AsyncUdpClient()
        {
            // 本機節點
            localEP = new IPEndPoint(IPAddress.Any, listenPort);
            // 遠程節點
            remoteEP = new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], remotePort);
            // 實例化
            udpReceive = new UdpClient(localEP);
            udpSend = new UdpClient();

            // 分別實例化udpSendState、udpReceiveState
            udpSendState = new UdpState();
            udpSendState.ipEndPoint = remoteEP;
            udpSendState.udpClient = udpSend;

            udpReceiveState = new UdpState();
            udpReceiveState.ipEndPoint = remoteEP;
            udpReceiveState.udpClient = udpReceive;

            //receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //receiveSocket.Bind(localEP);

            //sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            //sendSocket.Bind(remoteEP);
        }
        // 發送函數
        public void SendMsg()
        {
            udpSend.Connect(remoteEP);

            //Thread t = new Thread(new ThreadStart(ReceiveMessages));
            //t.Start();
            Byte[] sendBytes;
            string message;
            while (true)
            {
                message = "Client" + (counter++).ToString();
                lock (this)
                {
                    sendBytes = Encoding.ASCII.GetBytes(message);
                    udpSendState.counter = counter;
                    // 調用發送回調函數
                    udpSend.BeginSend(sendBytes, sendBytes.Length, new AsyncCallback(SendCallback), udpSendState);
                    sendDone.WaitOne();
                    Thread.Sleep(200);
                    ReceiveMessages();
                }
            }
        }

        // 發送回調函數
        public void SendCallback(IAsyncResult iar)
        {
            UdpState udpState = iar.AsyncState as UdpState;
            if (iar.IsCompleted)
            {
                Console.WriteLine("第{0}個發送完畢!", udpState.counter);
                Console.WriteLine("number of bytes sent: {0}", udpState.udpClient.EndSend(iar));
                //if (udpState.counter == 10)
                //{
                //    udpState.udpClient.Close();
                //}
                sendDone.Set();
            }
        }

        // 接收函數
        public void ReceiveMessages()
        {
            lock (this)
            {
                udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
                receiveDone.WaitOne();
                Thread.Sleep(100);
            }
        }

        // 接收回調函數
        public void ReceiveCallback(IAsyncResult iar)
        {
            UdpState udpState = iar.AsyncState as UdpState;
            if (iar.IsCompleted)
            {
                Byte[] receiveBytes = udpState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
                string receiveString = Encoding.Unicode.GetString(receiveBytes);
                Console.WriteLine("Received: {0}", receiveString);
                receiveDone.Set();
            }
        }

        // 主函數
        public static void Main()
        {
            AsyncUdpClient auc = new AsyncUdpClient();
            auc.SendMsg();
            Console.Read();
        }
    }
}
技術分享

四、總結

  UDP的異步實現,具有更高的效率,應用實例見博文“基於UDP協議的網絡攝像頭的設計與實現”。

出處:http://www.cnblogs.com/sunev/archive/2012/08/15/2604190.html

基於C#的UDP協議的異步實現