基于C#的UDP协议的异步实现

一、摘要

  总结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

时间: 2024-10-10 11:18:47

基于C#的UDP协议的异步实现的相关文章

android实现基于TCP和UDP协议的即时通讯,含android端和服务器端

这几天学习了下在android中实现即时通讯的方法,一开始,自然是从基本的网络协议中开始尝试了,这样能够最大化的私人订制自己的应用,还能学习到更多的知识,好处多多,接下来就简单介绍下两种协议的不同点吧 TCP协议:提供IP环境下的数据可靠传输,它提供的服务包括数据流传送.可靠性.有效流控.全双工操作和多路复用.通过面向连接.端到端和可靠的数据包发送.就如给悬崖上的两人通信时,他必须先把桥建好,确认桥是没问题的情况下,才把信件交过去,以后大家每次通信时,都确认下桥没什么问题,再通过这座桥来回通信了

初识Socket通信:基于TCP和UDP协议学习网络编程

学习笔记: 1.基于TCP协议的Socket网络编程: (1)Socket类构造方法:在客户端和服务器端建立连接 Socket s = new Socket(hostName,port);以主机名和端口号作为参数来创建一个Socket对象. Socket s = new Socket(address,port);以InetAddress对象和端口号作为参数来创建一个Socket对象. 创建Socket对象时可能抛出UnknownHostException或IOException异常,必须捕获它们

Java学习总结(十三)——基于UDP协议网络编程

一.UDP网络编程1.面向无连接的数据传输,不可靠的,但效率高(音频,视频等).2.UDP一次发送的数据不能超过64kb.3.UDP编程所需要的类(1)DatagramSocket此类表示用来发送和接收数据报包的套接字(2)DatagramPacket此类表示数据报包方法:DatagramPacket(byte[]?buf, int?length, InetAddress?address, int?port)参数表示:buf - 包数据length - 包长度address - 目的地址port

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③  

TwinCAT 3中基于UDP协议通讯的C++实现

因为项目需要,学习了TwinCAT3中使用UDP协议进行通讯的基本知识.这个做个简单的笔记,方便以后查询. 1 概述 倍福为了实现从实时环境中直接访问网卡(network cards)专门提供了一个函数 “TCP/UDP Realtime”, 这个访问要么来自PLC(61131-3), 要么来自C++.这个函数对使用以下协议进行的通讯提供支持: TCP/IP UDP/IP ARP/Ping TC3中使用该函数实现网络通信的示意图如下所示: 不管使用何种协议, 在基于该协议的项目和TC3之间的通讯

JAVA基础知识之网络编程——-基于UDP协议的通信例子

UDP是一种不可靠的协议,它在通信两端各建立一个socket,这两个socket不会建立持久的通信连接,只会单方面向对方发送数据,不检查发送结果. java中基于UDP协议的通信使用DatagramSocket类的receive和send方法即可,但消息需要通过一个特定的类封装(DatagramPacket) 下面是一个基于UDP协议的通信的例子, 服务器端, 1 package udp; 2 3 import java.io.IOException; 4 import java.net.Dat

基于 UDP 协议的网络编程

类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序 UDP 数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP 数据报一定能够安全送到目的地,也不能确定什么时候可以抵达 DatagramPacket 对象封装了 UDP 数据报(<64k),在数据报中包含了发送端的 IP 地址和端口号以及接收端的 IP 地址和端口号 UDP 协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接 举例: publ

基于UDP协议的网络编程

UDP协议是一种不可靠的网络协议,它在通信实例的两端各建立一个Socket,但这两个Socket之间并没有虚拟链路,这两个Socket只是发送.接收数据报的对象. Java使用DatagramSocket代表基于UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报.Java使用DatagramPacket来代表数据报,DatagramSocket接收和发送数据都是通过DatagramPacket对象完成的. Datagr

Android基础入门教程——7.6.4 基于UDP协议的Socket通信

Android基础入门教程--7.6.4 基于UDP协议的Socket通信 标签(空格分隔): Android基础入门教程 本节引言: 本节给大家带来Socket的最后一节:基于UDP协议的Socket通信,在第一节中我们已经详细地 比较了两者的区别,TCP和UDP最大的区别在于是否需要客户端与服务端建立连接后才能进行 数据传输,如果你学了前两节TCP的,传输前先开服务端,accept,等客户端接入,然后获得 客户端socket然后进行IO操作,而UDP则不用,UDP以数据报作为数据的传输载体,