C#网络编程系列文章(八)之UdpClient实现同步UDP服务器

原创性声明

本文作者:小竹zz 本文地址 转载请注明出处

文章系列目录

C#网络编程系列文章(一)之Socket实现异步TCP服务器

C#网络编程系列文章(二)之Socket实现同步TCP服务器

C#网络编程系列文章(三)之TcpListener实现异步TCP服务器

C#网络编程系列文章(四)之TcpListener实现同步TCP服务器

C#网络编程系列文章(五)之Socket实现异步UDP服务器

C#网络编程系列文章(六)之Socket实现同步UDP服务器

C#网络编程系列文章(七)之UdpClient实现异步UDP服务器

C#网络编程系列文章(八)之UdpClient实现同步UDP服务器

本文介绍UdpClient 类在同步阻塞模式中为发送和接收无连接的 UDP 数据包而提供了简单的方法。因为 UDP 是一种无连接的传输协议,,所以你不需要在发送和接收数据之前建立任何远程主机连接。你只需要按照下列方式来建立默认的远程主机选项:使用远程主机名称和端口号作为参数来创建 UdpClient 类的实例。创建 UdpClient 类的实例然后调用 Connect 方法。你可以使用任何由 UdpClient 所提供的发送方法把数据发送给远程设备。然后使用 Receive 方法来接收来自于远程主机的数据。提示:如果你已经指定了一个默认的远程主机,就不要使用主机名称或者 IPEndPoint 来调用 Send 方法。如果你这样做,那么 UdpClient 将会抛出一个异常。

UdpClient 方法同样允许你发送和接收多点传送的数据包。而使用 JoinMulticastGroup 方法可以把 UdpClient 订阅到多点传送分组。也可以使用 DropMulticastGroup 方法把 UdpClient 从多点传送分组的订阅中取消。

本节介绍使用UdpClient实现一个同步的UDP服务器

UdpClient同步UDP服务器using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;using System.Threading;namespace NetFrame.Net.UDP.Listener.Synchronous{/// <summary>/// UdpClient 实现同步UDP服务器/// </summary>public class UDPServer{#region Fields/// <summary>/// 服务器程序允许的最大客户端连接数/// </summary>private int _maxClient;/// <summary>/// 当前的连接的客户端数/// </summary>//private int _clientCount;/// <summary>/// 服务器使用的异步UdpClient/// </summary>private UdpClient _server;/// <summary>/// 客户端会话列表/// </summary>//private List<UDPState> _clients;private bool disposed = false;/// <summary>/// 数据接受缓冲区/// </summary>private byte[] _recvBuffer;#endregion#region Properties/// <summary>/// 服务器是否正在运行/// </summary>public bool IsRunning { get; private set; }/// <summary>/// 监听的IP地址/// </summary>public IPAddress Address { get; private set; }/// <summary>/// 监听的端口/// </summary>public int Port { get; private set; }/// <summary>/// 通信使用的编码/// </summary>public Encoding Encoding { get; set; }#endregion#region 构造函数/// <summary>/// 同步UdpClient UDP服务器/// </summary>/// <param name="listenPort">监听的端口</param>public UDPServer(int listenPort): this(IPAddress.Any, listenPort,1024){}/// <summary>/// 同步UdpClient UDP服务器/// </summary>/// <param name="localEP">监听的终结点</param>public UDPServer(IPEndPoint localEP): this(localEP.Address, localEP.Port,1024){}/// <summary>/// 同步UdpClient UDP服务器/// </summary>/// <param name="localIPAddress">监听的IP地址</param>/// <param name="listenPort">监听的端口</param>/// <param name="maxClient">最大客户端数量</param>public UDPServer(IPAddress localIPAddress, int listenPort, int maxClient){this.Address = localIPAddress;this.Port = listenPort;this.Encoding = Encoding.Default;_maxClient = maxClient;//_clients = new List<AsyncUDPSocketState>();_server = new UdpClient(new IPEndPoint(this.Address, this.Port));_recvBuffer=new byte[_server.Client.ReceiveBufferSize];}#endregion#region Method/// <summary>/// 启动服务器/// </summary>/// <returns>异步TCP服务器</returns>public void Start(){if (!IsRunning){IsRunning = true;_server.EnableBroadcast = true;new Thread(ReceiveData).Start();}}/// <summary>/// 停止服务器/// </summary>public void Stop(){if (IsRunning){IsRunning = false;_server.Close();//TODO 关闭对所有客户端的连接}}/// <summary>/// 同步接收数据的方法/// </summary>/// <param name="ar"></param>private void ReceiveData(){IPEndPoint remote = null;while (true){byte[] buffer = null;try{buffer = _server.Receive(ref remote);}catch (Exception){//异常处理操作return;}if (buffer == null || buffer.Length == 0) return;//TODO 数据包收到触发事件RaiseDataReceived(null);}}/// <summary>/// 同步发送数据/// </summary>/// <param name="msg"></param>/// <param name="remote"></param>public void Send(string msg, IPEndPoint remote){byte[] data = Encoding.Default.GetBytes(msg);try{_server.Send(data, data.Length, remote);}catch (Exception){//TODO 异常处理RaiseOtherException(null);}}#endregion#region 事件/// <summary>/// 接收到数据事件/// </summary>public event EventHandler<UDPEventArgs> DataReceived;private void RaiseDataReceived(UDPState state){if (DataReceived != null){DataReceived(this, new UDPEventArgs(state));}}/// <summary>/// 数据发送完毕事件/// </summary>public event EventHandler<UDPEventArgs> CompletedSend;/// <summary>/// 触发数据发送完毕的事件/// </summary>/// <param name="state"></param>private void RaiseCompletedSend(UDPState state){if (CompletedSend != null){CompletedSend(this, new UDPEventArgs(state));}}/// <summary>/// 网络错误事件/// </summary>public event EventHandler<UDPEventArgs> NetError;/// <summary>/// 触发网络错误事件/// </summary>/// <param name="state"></param>private void RaiseNetError(UDPState state){if (NetError != null){NetError(this, new UDPEventArgs(state));}}/// <summary>/// 异常事件/// </summary>public event EventHandler<UDPEventArgs> OtherException;/// <summary>/// 触发异常事件/// </summary>/// <param name="state"></param>private void RaiseOtherException(UDPState state, string descrip){if (OtherException != null){OtherException(this, new UDPEventArgs(descrip, state));}}private void RaiseOtherException(UDPState state){RaiseOtherException(state, "");}#endregion#region Close/// <summary>/// 关闭一个与客户端之间的会话/// </summary>/// <param name="state">需要关闭的客户端会话对象</param>public void Close(UDPState state){if (state != null){//_clients.Remove(state);//_clientCount–;//TODO 触发关闭事件}}/// <summary>/// 关闭所有的客户端会话,与所有的客户端连接会断开/// </summary>public void CloseAllClient(){//foreach (AsyncUDPSocketState client in _clients)//{// Close(client);//}//_clientCount = 0;//_clients.Clear();}#endregion#region 释放/// <summary>/// Performs application-defined tasks associated with freeing,/// releasing, or resetting unmanaged resources./// </summary>public void Dispose(){Dispose(true);GC.SuppressFinalize(this);}/// <summary>/// Releases unmanaged and – optionally – managed resources/// </summary>/// <param name="disposing"><c>true</c> to release/// both managed and unmanaged resources; <c>false</c>/// to release only unmanaged resources.</param>protected virtual void Dispose(bool disposing){if (!this.disposed){if (disposing){try{Stop();if (_server != null){_server = null;}}catch (SocketException){//TODORaiseOtherException(null);}}disposed = true;}}#endregion}}用户状态封装类using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Net;namespace NetFrame.Net.UDP.Listener.Synchronous{public class UDPState{// Client socket.public UdpClient udpClient = null;// Size of receive buffer.public const int BufferSize = 1024;// Receive buffer.public byte[] buffer = new byte[BufferSize];// Received data string.public StringBuilder sb = new StringBuilder();public IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);}}服务器事件参数类using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace NetFrame.Net.UDP.Listener.Synchronous{/// <summary>/// UdpClient 同步UDP服务器事件类/// </summary>public class UDPEventArgs : EventArgs{/// <summary>/// 提示信息/// </summary>public string _msg;/// <summary>/// 客户端状态封装类/// </summary>public UDPState _state;/// <summary>/// 是否已经处理过了/// </summary>public bool IsHandled { get; set; }public UDPEventArgs(string msg){this._msg = msg;IsHandled = false;}public UDPEventArgs(UDPState state){this._state = state;IsHandled = false;}public UDPEventArgs(string msg, UDPState state){this._msg = msg;this._state = state;IsHandled = false;}}}

记录沿途的心情。那样的生活才是我想要的。

C#网络编程系列文章(八)之UdpClient实现同步UDP服务器

相关文章:

你感兴趣的文章:

标签云: