您的位置:首页 > 理论基础 > 计算机网络

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

2017-12-13 10:03 603 查看


原创性声明

本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处


文章系列目录

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服务器

[csharp] view
plain copy

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)

{

//TODO

RaiseOtherException(null);

}

}

disposed = true;

}

}

#endregion

}

}

用户状态封装类

[csharp] view
plain copy

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);

}

}

服务器事件参数类

[csharp] view
plain copy

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;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: