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

1、摘要

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

 

2、實驗平臺

  visual studio 2010服務器

 

3、實驗實例

  服務器端代碼:網絡

複製代碼
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();
        }
    }
}
複製代碼

 

4、總結

  UDP的異步實現,具備更高的效率,應用實例見博文「基於UDP協議的網絡攝像頭的設計與實現」。函數

 

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

相關文章
相關標籤/搜索