转:https://www.cnblogs.com/yuanchenhui/p/asyn_scoket.html
前言
socket是软件之间通讯最常用的一种方式。c#实现socket通讯有很多中方法,其中效率最高就是异步通讯。
异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理,大家可以参考网上文章。
我这里想强调的是采用完成端口机制的异步通讯是windows下效率最高的通讯方式,没有之一!
异步通讯比同步通讯处理要难很多,代码编写中会遇到许多“坑“。如果没有经验,很难完成。
我搜集了大量资料,完成了对异步socket的封装。此库已用稳定高效的运行几个月。
纵观网上的资料,我还没有遇到一个满意的封装库。许多文章把数据收发和协议处理杂糅在一块,代码非常难懂,也无法扩展。
在编写该库时,避免以上缺陷。将逻辑处理层次化,模块化!同时实现了高可用性与高性能。
为了使大家对通讯效率有初步了解,先看测试图。


客户端和服务端都是本机测试,最大连接数为64422,套接字已耗尽!
主机配置情况

百兆带宽基本占满,cpu占用40%,我的电脑在空闲时,cpu占用大概20%,也就是说程序占用cpu 20%左右。
这个库是可扩展的,就是说即使10万个连接,收发同样的数据,cpu占用基本相同。
库的结构图

目标
- 即可作为服务端(监听)也可以作为客户端(主动连接)使用。
- 可以适应任何网络协议。收发的数据针对字节流或一个完整的包。对协议内容不做处理。
- 高可用性。将复杂的底层处理封装,对外接口非常友好。
- 高性能。最大限度优化处理。单机可支持数万连接,收发速度可达几百兆bit。
实现思路
网络处理逻辑可以分为以下几个部分:
- 网络监听 可以在多个端口实现监听。负责生成socket,生成的socket供后续处理。监听模块功能比较单一,如有必要,可对监听模块做进一步优化。
- 主动连接 可以异步或同步的连接对方。连接成功后,对socket的后续处理,与监听得到的socket完全一样。注:无论是监听得到的socket,还是连接得到的socket,后续处理完全一样。
- Socket收发处理 每个socket对应一个收发实例,socket收发只针对字节流处理。收发时,做了优化。比如发送时,对数据做了沾包,提高发送性能;接收时,一次投递1K的数据。
- 组包处理 一般数据包都有包长度指示;比如 报头的前俩个字节表示长度,根据这个值就可以组成一个完整的包。
NetListener 监听
using System.Net.Sockets;
private Socket listenSocket; public ListenParam _listenParam { get; set; } public event Action<ListenParam, AsyncSocketClient> OnAcceptSocket;
public NetListener(NetServer netServer)
public int _acceptAsyncCount = 0; public bool StartListen() IPEndPoint listenPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), _listenParam._port); listenSocket = new Socket(listenPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(listenPoint); listenSocket.Listen(200);
Thread thread1 = new Thread(new ThreadStart(NetProcess));
NetLogger.Log(string.Format("**监听异常!{0}", ex.Message));
AutoResetEvent _acceptEvent = new AutoResetEvent(false); private void NetProcess() _acceptEvent.WaitOne(1000 * 10);
private void DealNewAccept() if(_acceptAsyncCount <= 10)
AsyncSocketClient client = _newSocketClientList.GetObj();
NetLogger.Log(string.Format("DealNewAccept 异常 {0}***{1}", ex.Message, ex.StackTrace));
private void DealNewAccept(AsyncSocketClient client) client.SendBufferByteCount = _netServer.SendBufferBytePerClient; OnAcceptSocket?.Invoke(_listenParam, client);
private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs) Interlocked.Decrement(ref _acceptAsyncCount); acceptEventArgs.Completed -= AcceptEventArg_Completed; ProcessAccept(acceptEventArgs); NetLogger.Log(string.Format("AcceptEventArg_Completed {0}***{1}", ex.Message, ex.StackTrace));
public bool StartAccept() SocketAsyncEventArgs acceptEventArgs = new SocketAsyncEventArgs(); acceptEventArgs.Completed += AcceptEventArg_Completed;
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArgs); Interlocked.Increment(ref _acceptAsyncCount);
Interlocked.Decrement(ref _acceptAsyncCount); acceptEventArgs.Completed -= AcceptEventArg_Completed; ProcessAccept(acceptEventArgs);
ObjectPool<AsyncSocketClient> _newSocketClientList = new ObjectPool<AsyncSocketClient>(); private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) if (acceptEventArgs.AcceptSocket != null) AsyncSocketClient client = new AsyncSocketClient(acceptEventArgs.AcceptSocket); client.CreateClientInfo(this);
_newSocketClientList.PutObj(client); NetLogger.Log(string.Format("ProcessAccept {0}***{1}", ex.Message, ex.StackTrace));
NetConnectManage连接处理
using System.Net.Sockets;
public event Action<SocketEventParam, AsyncSocketClient> OnSocketConnectEvent;
public bool ConnectAsyn(string peerIp, int peerPort, object tag) Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); SocketAsyncEventArgs socketEventArgs = new SocketAsyncEventArgs(); socketEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(peerIp), peerPort); socketEventArgs.Completed += SocketConnect_Completed;
SocketClientInfo clientInfo = new SocketClientInfo(); socketEventArgs.UserToken = clientInfo; clientInfo.PeerIp = peerIp; clientInfo.PeerPort = peerPort;
bool willRaiseEvent = socket.ConnectAsync(socketEventArgs); ProcessConnect(socketEventArgs); socketEventArgs.Completed -= SocketConnect_Completed; socketEventArgs.Dispose(); NetLogger.Log("ConnectAsyn",ex);
private void SocketConnect_Completed(object sender, SocketAsyncEventArgs socketEventArgs) ProcessConnect(socketEventArgs); socketEventArgs.Completed -= SocketConnect_Completed; socketEventArgs.Dispose();
private void ProcessConnect(SocketAsyncEventArgs socketEventArgs) SocketClientInfo clientInfo = socketEventArgs.UserToken as SocketClientInfo; if (socketEventArgs.SocketError == SocketError.Success) DealConnectSocket(socketEventArgs.ConnectSocket, clientInfo); SocketEventParam socketParam = new SocketEventParam(EN_SocketEvent.connect, null); socketParam.ClientInfo = clientInfo; OnSocketConnectEvent?.Invoke(socketParam, null);
void DealConnectSocket(Socket socket, SocketClientInfo clientInfo) clientInfo.SetClientInfo(socket);
AsyncSocketClient client = new AsyncSocketClient(socket); client.SetClientInfo(clientInfo);
SocketEventParam socketParam = new SocketEventParam(EN_SocketEvent.connect, socket); socketParam.ClientInfo = clientInfo; OnSocketConnectEvent?.Invoke(socketParam, client);
public bool Connect(string peerIp, int peerPort, object tag, out Socket socket) Socket socketTmp = new Socket(SocketType.Stream, ProtocolType.Tcp);
SocketClientInfo clientInfo = new SocketClientInfo(); clientInfo.PeerIp = peerIp; clientInfo.PeerPort = peerPort;
EndPoint remoteEP = new IPEndPoint(IPAddress.Parse(peerIp), peerPort); socketTmp.Connect(remoteEP); if (!socketTmp.Connected)
DealConnectSocket(socketTmp, clientInfo); NetLogger.Log(string.Format("连接对方:({0}:{1})出错!", peerIp, peerPort), ex);
AsyncSocketClient socket收发处理
using System.Collections.Generic; using System.Diagnostics; using System.Net.Sockets;
public class AsyncSocketClient public static int IocpReadLen = 1024;
public readonly Socket ConnectSocket;
protected SocketAsyncEventArgs m_receiveEventArgs; public SocketAsyncEventArgs ReceiveEventArgs { get { return m_receiveEventArgs; } set { m_receiveEventArgs = value; } } protected byte[] m_asyncReceiveBuffer;
protected SocketAsyncEventArgs m_sendEventArgs; public SocketAsyncEventArgs SendEventArgs { get { return m_sendEventArgs; } set { m_sendEventArgs = value; } } protected byte[] m_asyncSendBuffer;
public event Action<AsyncSocketClient, byte[]> OnReadData; public event Action<AsyncSocketClient, int> OnSendData; public event Action<AsyncSocketClient> OnSocketClose;
static object releaseLock = new object(); public static int createCount = 0; public static int releaseCount = 0;
public AsyncSocketClient(Socket socket)
m_receiveEventArgs = new SocketAsyncEventArgs(); m_asyncReceiveBuffer = new byte[IocpReadLen]; m_receiveEventArgs.AcceptSocket = ConnectSocket; m_receiveEventArgs.Completed += ReceiveEventArgs_Completed;
m_sendEventArgs = new SocketAsyncEventArgs(); m_asyncSendBuffer = new byte[IocpReadLen * 2]; m_sendEventArgs.AcceptSocket = ConnectSocket; m_sendEventArgs.Completed += SendEventArgs_Completed;
SocketClientInfo _clientInfo;
public SocketClientInfo ClientInfo
internal void CreateClientInfo(NetListener netListener) _clientInfo = new SocketClientInfo(); _clientInfo.Tag = netListener._listenParam._tag; IPEndPoint ip = ConnectSocket.LocalEndPoint as IPEndPoint; Debug.Assert(netListener._listenParam._port == ip.Port);
_clientInfo.LocalIp = ip.Address.ToString(); _clientInfo.LocalPort = netListener._listenParam._port;
ip = ConnectSocket.RemoteEndPoint as IPEndPoint; _clientInfo.PeerIp = ip.Address.ToString(); _clientInfo.PeerPort = ip.Port; NetLogger.Log("CreateClientInfo", ex); internal void SetClientInfo(SocketClientInfo clientInfo) _clientInfo = clientInfo;
bool _inReadPending = false; public EN_SocketReadResult ReadNextData() return EN_SocketReadResult.ReadError; return EN_SocketReadResult.InAsyn; if(!ConnectSocket.Connected) return EN_SocketReadResult.ReadError;
m_receiveEventArgs.SetBuffer(m_asyncReceiveBuffer, 0, m_asyncReceiveBuffer.Length); bool willRaiseEvent = ConnectSocket.ReceiveAsync(ReceiveEventArgs); //投递接收请求 return EN_SocketReadResult.ReadError; return EN_SocketReadResult.HaveRead; return EN_SocketReadResult.InAsyn; NetLogger.Log("ReadNextData", ex); return EN_SocketReadResult.ReadError;
private void ProcessReceive() if (ReceiveEventArgs.BytesTransferred > 0 && ReceiveEventArgs.SocketError == SocketError.Success) int offset = ReceiveEventArgs.Offset; int count = ReceiveEventArgs.BytesTransferred;
byte[] readData = new byte[count]; Array.Copy(m_asyncReceiveBuffer, offset, readData, 0, count);
OnReadData?.Invoke(this, readData);
private void ReceiveEventArgs_Completed(object sender, SocketAsyncEventArgs e)
bool _socketError = false; private void OnReadError() if (_socketError == false) OnSocketClose?.Invoke(this);
int _sendBufferByteCount = 102400; public int SendBufferByteCount return _sendBufferByteCount; _sendBufferByteCount = 1024; _sendBufferByteCount = value;
SendBufferPool _sendDataPool = new SendBufferPool(); internal EN_SendDataResult PutSendData(byte[] data)
private void SendEventArgs_Completed(object sender, SocketAsyncEventArgs sendEventArgs) ProcessSend(m_sendEventArgs);
if (sendEventArgs.SocketError == SocketError.Success) sendCount = sendEventArgs.BytesTransferred; OnSendData?.Invoke(this, sendCount);
NetLogger.Log("SendEventArgs_Completed", ex);
private bool ProcessSend(SocketAsyncEventArgs sendEventArgs) if (sendEventArgs.SocketError == SocketError.Success)
private int GetSendData() byte[] data = _sendDataPool.GetObj(); Array.Copy(data, 0, m_asyncSendBuffer, dataLen, data.Length); if (dataLen > IocpReadLen) private void OnSendError() if (_socketError == false) OnSocketClose?.Invoke(this);
internal void CloseSocket() NetLogger.Log("CloseSocket", ex);
static object socketCloseLock = new object(); public static int closeSendCount = 0; public static int closeReadCount = 0;
bool _disposeSend = false; if (!_disposeSend && !_inSendPending)
m_sendEventArgs.SetBuffer(null, 0, 0); m_sendEventArgs.Completed -= SendEventArgs_Completed; m_sendEventArgs.Dispose();
bool _disposeRead = false; if (!_disposeRead && !_inReadPending)
m_receiveEventArgs.SetBuffer(null, 0, 0); m_receiveEventArgs.Completed -= ReceiveEventArgs_Completed; m_receiveEventArgs.Dispose(); private void CloseClient() NetLogger.Log("CloseClient", ex);
private List<byte[]> SplitData(byte[] data, int maxLen) List<byte[]> items = new List<byte[]>();
int itemLen = Math.Min(maxLen, data.Length - start); byte[] item = new byte[itemLen]; Array.Copy(data, start, item, 0, itemLen);
public enum EN_SocketReadResult
public enum EN_SocketSendResult
ObjectPool<byte[]> _bufferPool = new ObjectPool<byte[]>();
public Int64 _bufferByteCount = 0; public bool PutObj(byte[] obj) if (_bufferPool.PutObj(obj)) _bufferByteCount += obj.Length;
byte[] result = _bufferPool.GetObj(); _bufferByteCount -= result.Length;
NetServer 聚合其他类
using System.Collections.Generic; using System.Diagnostics; using System.Net.Sockets;
public Action<SocketEventParam> OnSocketPacketEvent;
public int SendBufferBytePerClient { get; set; } = 1024 * 100;
bool _serverStart = false; List<NetListener> _listListener = new List<NetListener>();
ClientPacketManage _clientPacketManage;
public Int64 SendByteCount { get; set; } public Int64 ReadByteCount { get; set; }
List<ListenParam> _listListenPort = new List<ListenParam>(); public void AddListenPort(int port, object tag) _listListenPort.Add(new ListenParam(port, tag)); /// <param name="listenFault">监听失败的端口</param> public bool StartListen(out List<int> listenFault)
_clientPacketManage = new ClientPacketManage(this); _clientPacketManage.OnSocketPacketEvent += PutClientPacket;
_netConnectManage.OnSocketConnectEvent += SocketConnectEvent;
Thread thread1 = new Thread(new ThreadStart(NetPacketProcess));
Thread thread2 = new Thread(new ThreadStart(NetSendProcess));
Thread thread3 = new Thread(new ThreadStart(NetReadProcess));
listenFault = new List<int>(); foreach (ListenParam param in _listListenPort) NetListener listener = new NetListener(this); listener._listenParam = param; listener.OnAcceptSocket += Listener_OnAcceptSocket; if (!listener.StartListen()) listenFault.Add(param._port); _listListener.Add(listener); NetLogger.Log(string.Format("监听成功!端口:{0}", param._port));
return listenFault.Count == 0;
public void PutClientPacket(SocketEventParam param) OnSocketPacketEvent?.Invoke(param);
get { return _packetMinLen; } get { return _packetMaxLen; }
/// <param name="minLen"></param> /// <param name="maxLen"></param> public void SetPacketParam(int minLen, int maxLen) Debug.Assert(minLen >= 0); Debug.Assert(maxLen > minLen);
public delegate int delegate_GetPacketTotalLen(byte[] data, int offset); public delegate_GetPacketTotalLen GetPacketTotalLen_Callback;
ObjectPoolWithEvent<SocketEventParam> _socketEventPool = new ObjectPoolWithEvent<SocketEventParam>(); private void NetPacketProcess() NetLogger.Log(string.Format("DealEventPool 异常 {0}***{1}", ex.Message, ex.StackTrace)); _socketEventPool.WaitOne(1000);
Dictionary<Socket, AsyncSocketClient> _clientGroup = new Dictionary<Socket, AsyncSocketClient>(); return _clientGroup.Count; public List<Socket> ClientList return _clientGroup.Keys.ToList();
private void DealEventPool() SocketEventParam param = _socketEventPool.GetObj();
if (param.SocketEvent == EN_SocketEvent.close) _clientGroup.Remove(param.Socket);
if (_packetMinLen == 0)//字节流处理 OnSocketPacketEvent?.Invoke(param); _clientPacketManage.PutSocketParam(param);
private void SocketConnectEvent(SocketEventParam param, AsyncSocketClient client) if (param.Socket == null || client == null) //连接失败
bool remove = _clientGroup.Remove(client.ConnectSocket); _clientGroup.Add(client.ConnectSocket, client);
client.OnSocketClose += Client_OnSocketClose; client.OnReadData += Client_OnReadData; client.OnSendData += Client_OnSendData;
_listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read)); _socketEventPool.PutObj(param); NetLogger.Log(string.Format("SocketConnectEvent 异常 {0}***{1}", ex.Message, ex.StackTrace));
internal void OnRcvPacketLenError(Socket socket, byte[] buffer, int offset, int packetLen) if (!_clientGroup.ContainsKey(socket))
NetLogger.Log(string.Format("报长度异常!包长:{0}", packetLen)); AsyncSocketClient client = _clientGroup[socket]; NetLogger.Log(string.Format("OnRcvPacketLenError 异常 {0}***{1}", ex.Message, ex.StackTrace));
private void Listener_OnAcceptSocket(ListenParam listenPatam, AsyncSocketClient client) bool remove = _clientGroup.Remove(client.ConnectSocket); _clientGroup.Add(client.ConnectSocket, client);
client.OnSocketClose += Client_OnSocketClose; client.OnReadData += Client_OnReadData; client.OnSendData += Client_OnSendData;
_listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read));
SocketEventParam param = new SocketEventParam(EN_SocketEvent.accept, client.ConnectSocket); param.ClientInfo = client.ClientInfo;
_socketEventPool.PutObj(param); NetLogger.Log(string.Format("Listener_OnAcceptSocket 异常 {0}***{1}", ex.Message, ex.StackTrace));
ObjectPoolWithEvent<SocketEventDeal> _listSendEvent = new ObjectPoolWithEvent<SocketEventDeal>(); private void NetSendProcess() _listSendEvent.WaitOne(1000);
ObjectPoolWithEvent<SocketEventDeal> _listReadEvent = new ObjectPoolWithEvent<SocketEventDeal>(); private void NetReadProcess() _listReadEvent.WaitOne(1000);
private void DealSendEvent() SocketEventDeal item = _listSendEvent.GetObj(); switch (item.SocketEvent) case EN_SocketDealEvent.send: EN_SocketSendResult result = item.Client.SendNextData(); if (result == EN_SocketSendResult.HaveSend) case EN_SocketDealEvent.read:
private void DealReadEvent() SocketEventDeal item = _listReadEvent.GetObj(); switch (item.SocketEvent) case EN_SocketDealEvent.read: EN_SocketReadResult result = item.Client.ReadNextData(); if (result == EN_SocketReadResult.HaveRead) case EN_SocketDealEvent.send:
private void Client_OnReadData(AsyncSocketClient client, byte[] readData) _listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read));
SocketEventParam param = new SocketEventParam(EN_SocketEvent.read, client.ConnectSocket); param.ClientInfo = client.ClientInfo; _socketEventPool.PutObj(param);
ReadByteCount += readData.Length; NetLogger.Log(string.Format("Client_OnReadData 异常 {0}***{1}", ex.Message, ex.StackTrace));
private void Client_OnSendData(AsyncSocketClient client, int sendCount) _listSendEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.send)); SendByteCount += sendCount;
private void Client_OnSocketClose(AsyncSocketClient client) SocketEventParam param = new SocketEventParam(EN_SocketEvent.close, client.ConnectSocket); param.ClientInfo = client.ClientInfo; _socketEventPool.PutObj(param); NetLogger.Log(string.Format("Client_OnSocketClose 异常 {0}***{1}", ex.Message, ex.StackTrace));
/// <param name="socket"></param> /// <param name="data"></param> public EN_SendDataResult SendData(Socket socket, byte[] data) return EN_SendDataResult.no_client; if (!_clientGroup.ContainsKey(socket)) return EN_SendDataResult.no_client; AsyncSocketClient client = _clientGroup[socket]; EN_SendDataResult result = client.PutSendData(data); if (result == EN_SendDataResult.ok) _listSendEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.send));
/// <param name="socket"></param> /// <param name="byteCount"></param> public bool SetClientSendBuffer(Socket socket, int byteCount) if (!_clientGroup.ContainsKey(socket)) AsyncSocketClient client = _clientGroup[socket]; client.SendBufferByteCount = byteCount;
NetConnectManage _netConnectManage = new NetConnectManage(); /// <param name="peerIp"></param> /// <param name="peerPort"></param> /// <param name="tag"></param> public bool ConnectAsyn(string peerIp, int peerPort, object tag) return _netConnectManage.ConnectAsyn(peerIp, peerPort, tag);
/// <param name="peerIp"></param> /// <param name="peerPort"></param> /// <param name="tag"></param> /// <param name="socket"></param> public bool Connect(string peerIp, int peerPort, object tag, out Socket socket) return _netConnectManage.Connect(peerIp, peerPort, tag, out socket);
public AsyncSocketClient Client { get; set; } public EN_SocketDealEvent SocketEvent { get; set; } public SocketEventDeal(AsyncSocketClient client, EN_SocketDealEvent socketEvent) SocketEvent = socketEvent;
库的使用
使用起来非常简单,示例如下
using System.Collections.Generic; using System.Net.Sockets; using System.Threading.Tasks;
public class SocketServer public Action<SocketEventParam> OnSocketEvent;
public Int64 SendByteCount return _netServer.SendByteCount; public Int64 ReadByteCount return _netServer.ReadByteCount;
EN_PacketType _packetType = EN_PacketType.byteStream; public void SetPacktType(EN_PacketType packetType) _packetType = packetType; if (packetType == EN_PacketType.byteStream) _netServer.SetPacketParam(0, 1024); _netServer.SetPacketParam(9, 1024);
public bool Init(List<int> listenPort) NetLogger.OnLogEvent += NetLogger_OnLogEvent; _netServer = new NetServer(); SetPacktType(_packetType); _netServer.GetPacketTotalLen_Callback += GetPacketTotalLen; _netServer.OnSocketPacketEvent += SocketPacketDeal;
foreach (int n in listenPort) _netServer.AddListenPort(n, n);
bool start = _netServer.StartListen(out listenFault);
int GetPacketTotalLen(byte[] data, int offset) if (MainWindow._packetType == EN_PacketType.znss) return GetPacketZnss(data, offset); return GetPacketAnzhiyuan(data, offset);
int GetPacketAnzhiyuan(byte[] data, int offset) int n = data[offset + 5] + 6;
int GetPacketZnss(byte[] data, int offset) int packetLen = (int)(data[4]) + 5;
public bool ConnectAsyn(string peerIp, int peerPort, object tag) return _netServer.ConnectAsyn(peerIp, peerPort, tag);
public bool Connect(string peerIp, int peerPort, object tag, out Socket socket) return _netServer.Connect(peerIp, peerPort, tag, out socket);
private void NetLogger_OnLogEvent(string message)
Dictionary<Socket, SocketEventParam> _clientGroup = new Dictionary<Socket, SocketEventParam>();
return _clientGroup.Count; public List<Socket> ClientList return _netServer.ClientList; return new List<Socket>(); void AddClient(SocketEventParam socketParam) _clientGroup.Remove(socketParam.Socket); _clientGroup.Add(socketParam.Socket, socketParam);
void RemoveClient(SocketEventParam socketParam) _clientGroup.Remove(socketParam.Socket);
ObjectPool<SocketEventParam> _readDataPool = new ObjectPool<SocketEventParam>();
public ObjectPool<SocketEventParam> ReadDataPool
private void SocketPacketDeal(SocketEventParam socketParam) OnSocketEvent?.Invoke(socketParam); if (socketParam.SocketEvent == EN_SocketEvent.read) if (MainWindow._isShowReadPacket) _readDataPool.PutObj(socketParam); else if (socketParam.SocketEvent == EN_SocketEvent.accept) string peerIp = socketParam.ClientInfo.PeerIpPort; AppLog.Log(string.Format("客户端链接!本地端口:{0},对端:{1}", socketParam.ClientInfo.LocalPort, peerIp)); else if (socketParam.SocketEvent == EN_SocketEvent.connect) string peerIp = socketParam.ClientInfo.PeerIpPort; if (socketParam.Socket != null)
AppLog.Log(string.Format("连接对端成功!本地端口:{0},对端:{1}", socketParam.ClientInfo.LocalPort, peerIp)); AppLog.Log(string.Format("连接对端失败!本地端口:{0},对端:{1}", socketParam.ClientInfo.LocalPort, peerIp)); else if (socketParam.SocketEvent == EN_SocketEvent.close) MainWindow.MainWnd.OnSocketDisconnect(socketParam.Socket); RemoveClient(socketParam); string peerIp = socketParam.ClientInfo.PeerIpPort; AppLog.Log(string.Format("客户端断开!本地端口:{0},对端:{1},", socketParam.ClientInfo.LocalPort, peerIp));
public EN_SendDataResult SendData(Socket socket, byte[] data) MessageBox.Show("还没连接!"); return EN_SendDataResult.no_client; return _netServer.SendData(socket, data);
internal void SendToAll(byte[] data) foreach (Socket socket in _clientGroup.Keys)
博客原文:https://www.cnblogs.com/yuanchenhui/p/asyn_scoket.html
|