Udp 异步通信(三)
转自:https://blog.csdn.net/zhujunxxxxx/article/details/44258719
1)服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text; namespace UdpSocketServer
{
public class UdpServerAsync
{
#region Fields private int _maxClient; private Socket _serverSock; private List<EndPoint> _clients; private bool disposed = false; private byte[] _recvBuffer; #endregion #region Properties public bool IsRunning { get; private set; } public IPAddress Address { get; private set; } public int Port { get; private set; } public Encoding Encoding { get; set; } #endregion #region 构造函数 public UdpServerAsync(int listenPort)
: this(IPAddress.Any, listenPort, )
{
} public UdpServerAsync(IPEndPoint localEP)
: this(localEP.Address, localEP.Port, )
{
} public UdpServerAsync(IPAddress localIPAddress, int listenPort, int maxClient)
{
this.Address = localIPAddress;
this.Port = listenPort;
this.Encoding = Encoding.Default; _maxClient = maxClient; _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp); _recvBuffer = new byte[_serverSock.ReceiveBufferSize];
} #endregion #region Method public void Start()
{
if (!IsRunning)
{
IsRunning = true;
_serverSock.Bind(new IPEndPoint(this.Address, this.Port));
//_serverSock.Connect(new IPEndPoint(IPAddress.Any, 0)); SocketState so = new SocketState();
so.buffer = new byte[_serverSock.ReceiveBufferSize];
so.remote = new IPEndPoint(Address, Port); _serverSock.BeginReceiveFrom(so.buffer, , so.buffer.Length, SocketFlags.None,
ref so.remote, new AsyncCallback(ReceiveDataAsync), so);
}
} public void Stop()
{
if (IsRunning)
{
IsRunning = false;
_serverSock.Close();
}
} private void ReceiveDataAsync(IAsyncResult ar)
{
SocketState so = ar.AsyncState as SocketState; int len = -;
try
{
len = _serverSock.EndReceiveFrom(ar, ref so.remote);
so.recvSize = len;
//len = _serverSock.EndReceiveFrom(ar, ref sender); //EndReceiveFrom 和 EndReceive区别
//len = _serverSock.EndReceive(ar);
//TODO 处理数据 //触发数据收到事件
RaiseDataReceived(so);
}
catch (Exception)
{
//TODO 处理异常
RaiseOtherException(so);
}
finally
{
if (IsRunning && _serverSock != null)
_serverSock.BeginReceiveFrom(so.buffer, , so.buffer.Length, SocketFlags.None,
ref so.remote, new AsyncCallback(ReceiveDataAsync), so);
}
} public void Send(byte[] data, EndPoint remote)
{
try
{
RaisePrepareSend(null);
_serverSock.BeginSendTo(data, , data.Length, SocketFlags.None, remote, new AsyncCallback(SendDataEnd), _serverSock);
}
catch (Exception)
{
//TODO 异常处理
RaiseOtherException(null);
}
} private void SendDataEnd(IAsyncResult ar)
{
((Socket)ar.AsyncState).EndSendTo(ar);
RaiseCompletedSend(null);
} #endregion #region 事件 public event EventHandler<UDPMessage> DataReceived; private void RaiseDataReceived(SocketState state)
{
if (DataReceived != null)
{
DataReceived(this, new UDPMessage(state));
}
} /// <summary>
/// 发送数据前的事件
/// </summary>
public event EventHandler<UDPMessage> PrepareSend; /// <summary>
/// 触发发送数据前的事件
/// </summary>
/// <param name="state"></param>
private void RaisePrepareSend(SocketState state)
{
if (PrepareSend != null)
{
PrepareSend(this, new UDPMessage(state));
}
} /// <summary>
/// 数据发送完毕事件
/// </summary>
public event EventHandler<UDPMessage> CompletedSend; /// <summary>
/// 触发数据发送完毕的事件
/// </summary>
/// <param name="state"></param>
private void RaiseCompletedSend(SocketState state)
{
if (CompletedSend != null)
{
CompletedSend(this, new UDPMessage(state));
}
} /// <summary>
/// 网络错误事件
/// </summary>
public event EventHandler<UDPMessage> NetError;
/// <summary>
/// 触发网络错误事件
/// </summary>
/// <param name="state"></param>
private void RaiseNetError(SocketState state)
{
if (NetError != null)
{
NetError(this, new UDPMessage(state));
}
} /// <summary>
/// 异常事件
/// </summary>
public event EventHandler<UDPMessage> OtherException;
/// <summary>
/// 触发异常事件
/// </summary>
/// <param name="state"></param>
private void RaiseOtherException(SocketState state, string descrip)
{
if (OtherException != null)
{
OtherException(this, new UDPMessage(descrip, state));
}
}
private void RaiseOtherException(SocketState state)
{
RaiseOtherException(state, "");
}
#endregion #region Close
/// <summary>
/// 关闭一个与客户端之间的会话
/// </summary>
/// <param name="state">需要关闭的客户端会话对象</param>
public void Close(SocketState 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 (_serverSock != null)
{
_serverSock = null;
}
}
catch (SocketException)
{
//TODO
RaiseOtherException(null);
}
}
disposed = true;
}
}
#endregion
}
}
2)客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text; namespace UdpSocketClient
{
public class UDPClientAsync
{
#region 字段 public Socket udpClient; public EndPoint endPoint; private SocketState state; #endregion #region 属性 public IPAddress Address { get; private set; } public int Port { get; private set; } #endregion #region 构造函数 public UDPClientAsync(IPAddress ipAddress,int port)
{
this.Address = ipAddress;
this.Port = port;
endPoint = new IPEndPoint(Address, Port);
udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
} public UDPClientAsync(IPEndPoint ipEndPoint)
:this(ipEndPoint.Address,ipEndPoint.Port)
{
} #endregion #region Method public void Send(byte[] bytes)
{
udpClient.BeginSendTo(bytes, , bytes.Length, SocketFlags.None, endPoint, iAsyncResult=>
{
udpClient.EndSendTo(iAsyncResult); RaiseDataSend();
}, null);
} public void Receive()
{
state = new UdpSocketClient.SocketState();
state.buffer = new byte[udpClient.ReceiveBufferSize];
state.remote = new IPEndPoint(Address, Port); udpClient.BeginReceiveFrom(state.buffer, , state.buffer.Length, SocketFlags.None, ref state.remote,
new AsyncCallback(DataReceivedCallBack), null);
} private void DataReceivedCallBack(IAsyncResult iAsyncResult)
{
int len = -;
try
{
len = udpClient.EndReceiveFrom(iAsyncResult, ref state.remote);
state.recvSize = len; RaiseDataReceived(state);
}
catch(Exception ex)
{
RaiseErrorException(ex.Message);
} //if (udpClient != null)
//{
// udpClient.BeginReceiveFrom(state.buffer, 0, state.buffer.Length, SocketFlags.None, ref state.remote,
// new AsyncCallback(DataReceivedCallBack), null);
//}
} public void Close()
{
udpClient.Shutdown(SocketShutdown.Both); udpClient.Close();
GC.Collect();
} #endregion #region 事件 public event EventHandler<UDPMessage> DataReceived; private void RaiseDataReceived(SocketState state)
{
if(DataReceived!=null)
{
DataReceived(this, new UdpSocketClient.UDPMessage(state));
}
} public event EventHandler<UDPMessage> DataSend; private void RaiseDataSend()
{
if(DataSend!=null)
{
DataSend(this, null);
}
} public event EventHandler<UDPMessage> ErrorException; private void RaiseErrorException(string msg)
{
if(ErrorException!=null)
{
ErrorException(this, new UdpSocketClient.UDPMessage(msg));
}
} #endregion
}
}
3)消息类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text; namespace UdpSocketServer
{
public class SocketState
{
public Socket workSocket = null; public byte[] buffer; public int recvSize; public EndPoint remote; public string Diagram
{
get
{
byte[] data = new byte[recvSize];
Array.ConstrainedCopy(buffer, , data, , recvSize);
//_datagram = Encoding.Default.GetString(data);
return Encoding.Default.GetString(data);
}
}
}
}
4)服务端信息类
using System.Collections.Generic;
using System.Linq;
using System.Text;
{
public class UDPMessage : EventArgs
{
/// <summary>
/// 提示信息
/// </summary>
public string _msg;
/// 客户端状态封装类
/// </summary>
public SocketState _state;
/// 是否已经处理过了
/// </summary>
public bool IsHandled { get; set; }
{
this._msg = msg;
IsHandled = false;
}
public UDPMessage(SocketState state)
{
this._state = state;
IsHandled = false;
}
public UDPMessage(string msg, SocketState state)
{
this._msg = msg;
this._state = state;
IsHandled = false;
}
}
}
Udp 异步通信(三)的更多相关文章
- TCP/IP协议 | TCP协议 | UDP协议 | 三次握手四次挥手
TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP.SMTP.TCP.UDP.IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP ...
- UDP异步通信
先看效果图 Server: using System; using System.Collections.Generic; using System.Text; using System.Net; u ...
- C#UDP异步通信
using SetingDemo.LogHelp;using SetingDemo.SingleRowDeclare;using System;using System.Collections.Gen ...
- 基于socket的TCP和UDP编程
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- (转)基于socket的TCP和UDP编程
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- UDP 打洞 原理解释
终于找到了一份满意的UDP打洞原理解释,附上正文,自己整理了一下源码 3.3. UDP hole punching UDP打洞技术 The third technique, and the one o ...
- 初识-----基于Socket的UDP和TCP编程及测试代码
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- 基于Socket的UDP和TCP编程介绍
一.概述 TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议. TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流 ...
- socket http tcp udp ip 协议
Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接. socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作 ...
随机推荐
- Merge into 语句实例
/*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,连接条件匹配 ...
- 使用 BeanDefinition 描述 Spring Bean
什么是BeanDefinition 在Java中,一切皆对象.在JDK中使用java.lang.Class来描述类这个对象. 在Spring中,存在bean这样一个概念,那Spring又是怎么抽象be ...
- JavaScript系列:函数式编程(开篇)
前言: 上一篇介绍了 函数回调,高阶函数以及函数柯里化等高级函数应用,同时,因为正在学习JavaScript·函数式编程,想整理一下函数式编程中,对于我们日常比较有用的部分. 为什么函数式编程很重要? ...
- k阶斐波那契数列fibonacci第n项求值
已知K阶斐波那契数列定义为:f0 = 0, f1 = 0, … , fk-2 = 0, fk-1 = 1;fn = fn-1 + fn-2 + … + fn-k , n = k , k + 1, … ...
- React antd如何实现<Upload>组件上传附件再次上传已清除附件缓存问题。
最近在公司做React+antd的项目,遇到一个上传组件的问题,即上传附件成功后,文件展示处仍然还有之前上传附件的缓存信息,需要解决的问题是,要把上一次上传的附件缓存在上传成功或者取消后,可以进行清除 ...
- 03 python基础作业(一)
1.将['alex','eric',’rain’]用下划线拼接成字符串.(['alex','eric',123]呢?) li=['alex','eric','rain'] v='_'.join(li) ...
- 从零开始入门 K8s | Kubernetes 网络概念及策略控制
作者 | 阿里巴巴高级技术专家 叶磊 一.Kubernetes 基本网络模型 本文来介绍一下 Kubernetes 对网络模型的一些想法.大家知道 Kubernetes 对于网络具体实现方案,没有什 ...
- .net core运用application/x-www-form-urlencoded发起post请求
通常情况下都是使用 application/json发起post请求,但是有的.net 接口只接收 application/x-www-form-urlencoded 例如: { name:" ...
- 想转行做3D游戏模型,如何快速入行
随着技术和硬件迭代,3D建模,广泛运用在游戏,影视,动画,VR等领域,而且就业面非常广. 由于3D美术设计师薪资和前景确实都不错,很多同学想进入这个行业,从事相关工作,但是没有一个整体的学习思路和规划 ...
- 2019头条java面试总结 (包含面试题解析)
2019滴滴java面试总结 (包含面试题) 本人8年开发经验.今年年初找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.滴滴等公司offer,岗位是Java后端开发. 面试了很多家公司,感觉大部分 ...