前言
socket是软件之间通讯最常用的一种方式。c#实现socket通讯有很多中方法,其中效率最高就是异步通讯。
异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理,大家可以参考网上文章。
我这里想强调的是采用完成端口机制的异步通讯是windows下效率最高的通讯方式,没有之一!
异步通讯比同步通讯处理要难很多,代码编写中会遇到许多“坑“。如果没有经验,很难完成。
我搜集了大量资料,完成了对异步socket的封装。此库已用稳定高效的运行几个月。
纵观网上的资料,我还没有遇到一个满意的封装库。许多文章把数据收发和协议处理杂糅在一块,代码非常难懂,也无法扩展。
在编写该库时,避免以上缺陷。将逻辑处理层次化,模块化!同时实现了高可用性与高性能。
为了使大家对通讯效率有初步了解,先看测试图。
客户端和服务端都是本机测试,最大连接数为64422,套接字已耗尽!
主机配置情况
百兆带宽基本占满,cpu占用40%,我的电脑在空闲时,cpu占用大概20%,也就是说程序占用cpu 20%左右。
这个库是可扩展的,就是说即使10万个连接,收发同样的数据,cpu占用基本相同。
网络处理逻辑可以分为以下几个部分:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace IocpCore
{
class NetListener
{
private Socket listenSocket;
public ListenParam _listenParam { get; set; }
public event Action OnAcceptSocket;
bool start;
NetServer _netServer;
public NetListener(NetServer netServer)
{
_netServer = netServer;
}
public int _acceptAsyncCount = 0;
public bool StartListen()
{
try
{
start = true;
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));
thread1.Start();
StartAccept();
return true;
}
catch (Exception ex)
{
NetLogger.Log(string.Format("**监听异常!{0}", ex.Message));
return false;
}
}
AutoResetEvent _acceptEvent = new AutoResetEvent(false);
private void NetProcess()
{
while (start)
{
DealNewAccept();
_acceptEvent.WaitOne(1000 * 10);
}
}
private void DealNewAccept()
{
try
{
if(_acceptAsyncCount <= 10)
{
StartAccept();
}
while (true)
{
AsyncSocketClient client = _newSocketClientList.GetObj();
if (client == null)
break;
DealNewAccept(client);
}
}
catch (Exception ex)
{
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)
{
try
{
Interlocked.Decrement(ref _acceptAsyncCount);
_acceptEvent.Set();
acceptEventArgs.Completed -= AcceptEventArg_Completed;
ProcessAccept(acceptEventArgs);
}
catch (Exception ex)
{
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);
if (!willRaiseEvent)
{
Interlocked.Decrement(ref _acceptAsyncCount);
_acceptEvent.Set();
acceptEventArgs.Completed -= AcceptEventArg_Completed;
ProcessAccept(acceptEventArgs);
}
return true;
}
ObjectPool _newSocketClientList = new ObjectPool();
private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
{
try
{
using (acceptEventArgs)
{
if (acceptEventArgs.AcceptSocket != null)
{
AsyncSocketClient client = new AsyncSocketClient(acceptEventArgs.AcceptSocket);
client.CreateClientInfo(this);
_newSocketClientList.PutObj(client);
_acceptEvent.Set();
}
}
}
catch (Exception ex)
{
NetLogger.Log(string.Format("ProcessAccept {0}***{1}", ex.Message, ex.StackTrace));
}
}
}
}
1 using System;
2 using System.Net;
3 using System.Net.Sockets;
4
5 namespace IocpCore
6 {
7 class NetConnectManage
8 {
9 public event Action OnSocketConnectEvent;
10
11 public bool ConnectAsyn(string peerIp, int peerPort, object tag)
12 {
13 try
14 {
15 Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
16 SocketAsyncEventArgs socketEventArgs = new SocketAsyncEventArgs();
17 socketEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(peerIp), peerPort);
18 socketEventArgs.Completed += SocketConnect_Completed;
19
20 SocketClientInfo clientInfo = new SocketClientInfo();
21 socketEventArgs.UserToken = clientInfo;
22 clientInfo.PeerIp = peerIp;
23 clientInfo.PeerPort = peerPort;
24 clientInfo.Tag = tag;
25
26 bool willRaiseEvent = socket.ConnectAsync(socketEventArgs);
27 if (!willRaiseEvent)
28 {
29 ProcessConnect(socketEventArgs);
30 socketEventArgs.Completed -= SocketConnect_Completed;
31 socketEventArgs.Dispose();
32 }
33 return true;
34 }
35 catch (Exception ex)
36 {
37 NetLogger.Log("ConnectAsyn",ex);
38 return false;
39 }
40 }
41
42 private void SocketConnect_Completed(object sender, SocketAsyncEventArgs socketEventArgs)
43 {
44 ProcessConnect(socketEventArgs);
45 socketEventArgs.Completed -= SocketConnect_Completed;
46 socketEventArgs.Dispose();
47 }
48
49 private void ProcessConnect(SocketAsyncEventArgs socketEventArgs)
50 {
51 SocketClientInfo clientInfo = socketEventArgs.UserToken as SocketClientInfo;
52 if (socketEventArgs.SocketError == SocketError.Success)
53 {
54 DealConnectSocket(socketEventArgs.ConnectSocket, clientInfo);
55 }
56 else
57 {
58 SocketEventParam socketParam = new SocketEventParam(EN_SocketEvent.connect, null);
59 socketParam.ClientInfo = clientInfo;
60 OnSocketConnectEvent?.Invoke(socketParam, null);
61 }
62 }
63
64
65 void DealConnectSocket(Socket socket, SocketClientInfo clientInfo)
66 {
67 clientInfo.SetClientInfo(socket);
68
69 AsyncSocketClient client = new AsyncSocketClient(socket);
70 client.SetClientInfo(clientInfo);
71
72 //触发事件
73 SocketEventParam socketParam = new SocketEventParam(EN_SocketEvent.connect, socket);
74 socketParam.ClientInfo = clientInfo;
75 OnSocketConnectEvent?.Invoke(socketParam, client);
76 }
77
78 public bool Connect(string peerIp, int peerPort, object tag, out Socket socket)
79 {
80 socket = null;
81 try
82 {
83 Socket socketTmp = new Socket(SocketType.Stream, ProtocolType.Tcp);
84
85 SocketClientInfo clientInfo = new SocketClientInfo();
86 clientInfo.PeerIp = peerIp;
87 clientInfo.PeerPort = peerPort;
88 clientInfo.Tag = tag;
89
90 EndPoint remoteEP = new IPEndPoint(IPAddress.Parse(peerIp), peerPort);
91 socketTmp.Connect(remoteEP);
92 if (!socketTmp.Connected)
93 return false;
94
95 DealConnectSocket(socketTmp, clientInfo);
96 socket = socketTmp;
97 return true;
98 }
99 catch (Exception ex)
100 {
101 NetLogger.Log(string.Format("连接对方:({0}:{1})出错!", peerIp, peerPort), ex);
102 return false;
103 }
104 }
105 }
106 }
View Code
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5 using System.Net.Sockets;
6 using System.Threading;
7
8 namespace IocpCore
9 {
10 public class NetServer
11 {
12 public Action OnSocketPacketEvent;
13
14 //每个连接发送缓冲大小
15 public int SendBufferBytePerClient { get; set; } = 1024 * 100;
16
17 bool _serverStart = false;
18 List _listListener = new List();
19
20 //负责对收到的字节流 组成完成的包
21 ClientPacketManage _clientPacketManage;
22
23 public Int64 SendByteCount { get; set; }
24 public Int64 ReadByteCount { get; set; }
25
26 List _listListenPort = new List();
27 public void AddListenPort(int port, object tag)
28 {
29 _listListenPort.Add(new ListenParam(port, tag));
30 }
31 ///
32 ///
33 ///
34 /// 监听失败的端口
35 ///
36 public bool StartListen(out List listenFault)
37 {
38 _serverStart = true;
39
40 _clientPacketManage = new ClientPacketManage(this);
41 _clientPacketManage.OnSocketPacketEvent += PutClientPacket;
42
43 _netConnectManage.OnSocketConnectEvent += SocketConnectEvent;
44
45 _listListener.Clear();
46 Thread thread1 = new Thread(new ThreadStart(NetPacketProcess));
47 thread1.Start();
48
49 Thread thread2 = new Thread(new ThreadStart(NetSendProcess));
50 thread2.Start();
51
52 Thread thread3 = new Thread(new ThreadStart(NetReadProcess));
53 thread3.Start();
54
55 listenFault = new List();
56 foreach (ListenParam param in _listListenPort)
57 {
58 NetListener listener = new NetListener(this);
59 listener._listenParam = param;
60 listener.OnAcceptSocket += Listener_OnAcceptSocket;
61 if (!listener.StartListen())
62 {
63 listenFault.Add(param._port);
64 }
65 else
66 {
67 _listListener.Add(listener);
68 NetLogger.Log(string.Format("监听成功!端口:{0}", param._port));
69 }
70 }
71
72 return listenFault.Count == 0;
73 }
74
75 public void PutClientPacket(SocketEventParam param)
76 {
77 OnSocketPacketEvent?.Invoke(param);
78 }
79
80 //获取包的最小长度
81 int _packetMinLen;
82 int _packetMaxLen;
83 public int PacketMinLen
84 {
85 get { return _packetMinLen; }
86 }
87 public int PacketMaxLen
88 {
89 get { return _packetMaxLen; }
90 }
91
92 ///
93 /// 设置包的最小和最大长度
94 /// 当minLen=0时,认为是接收字节流
95 ///
96 ///
97 ///
98 public void SetPacketParam(int minLen, int maxLen)
99 {
100 Debug.Assert(minLen >= 0);
101 Debug.Assert(maxLen > minLen);
102 _packetMinLen = minLen;
103 _packetMaxLen = maxLen;
104 }
105
106 //获取包的总长度
107 public delegate int delegate_GetPacketTotalLen(byte[] data, int offset);
108 public delegate_GetPacketTotalLen GetPacketTotalLen_Callback;
109
110 ObjectPoolWithEvent _socketEventPool = new ObjectPoolWithEvent();
111 private void NetPacketProcess()
112 {
113 while (_serverStart)
114 {
115 try
116 {
117 DealEventPool();
118 }
119 catch (Exception ex)
120 {
121 NetLogger.Log(string.Format("DealEventPool 异常 {0}***{1}", ex.Message, ex.StackTrace));
122 }
123 _socketEventPool.WaitOne(1000);
124 }
125 }
126
127 Dictionary _clientGroup = new Dictionary();
128 public int ClientCount
129 {
130 get
131 {
132 lock (_clientGroup)
133 {
134 return _clientGroup.Count;
135 }
136 }
137 }
138 public List ClientList
139 {
140 get
141 {
142 lock (_clientGroup)
143 {
144 return _clientGroup.Keys.ToList();
145 }
146 }
147 }
148
149 private void DealEventPool()
150 {
151 while (true)
152 {
153 SocketEventParam param = _socketEventPool.GetObj();
154 if (param == null)
155 return;
156
157 if (param.SocketEvent == EN_SocketEvent.close)
158 {
159 lock (_clientGroup)
160 {
161 _clientGroup.Remove(param.Socket);
162 }
163 }
164
165 if (_packetMinLen == 0)//字节流处理
166 {
167 OnSocketPacketEvent?.Invoke(param);
168 }
169 else
170 {
171 //组成一个完整的包 逻辑
172 _clientPacketManage.PutSocketParam(param);
173 }
174 }
175 }
176
177 private void SocketConnectEvent(SocketEventParam param, AsyncSocketClient client)
178 {
179 try
180 {
181 if (param.Socket == null || client == null) //连接失败
182 {
183
184 }
185 else
186 {
187 lock (_clientGroup)
188 {
189 bool remove = _clientGroup.Remove(client.ConnectSocket);
190 Debug.Assert(!remove);
191 _clientGroup.Add(client.ConnectSocket, client);
192 }
193
194 client.OnSocketClose += Client_OnSocketClose;
195 client.OnReadData += Client_OnReadData;
196 client.OnSendData += Client_OnSendData;
197
198 _listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read));
199 }
200 _socketEventPool.PutObj(param);
201 }
202 catch (Exception ex)
203 {
204 NetLogger.Log(string.Format("SocketConnectEvent 异常 {0}***{1}", ex.Message, ex.StackTrace));
205 }
206 }
207
208 internal void OnRcvPacketLenError(Socket socket, byte[] buffer, int offset, int packetLen)
209 {
210 try
211 {
212 lock (_clientGroup)
213 {
214 if (!_clientGroup.ContainsKey(socket))
215 {
216 Debug.Assert(false);
217 return;
218 }
219
220 NetLogger.Log(string.Format("报长度异常!包长:{0}", packetLen));
221 AsyncSocketClient client = _clientGroup[socket];
222 client.CloseSocket();
223 }
224 }
225 catch (Exception ex)
226 {
227 NetLogger.Log(string.Format("OnRcvPacketLenError 异常 {0}***{1}", ex.Message, ex.StackTrace));
228 }
229 }
230
231 #region listen port
232 private void Listener_OnAcceptSocket(ListenParam listenPatam, AsyncSocketClient client)
233 {
234 try
235 {
236 lock (_clientGroup)
237 {
238 bool remove = _clientGroup.Remove(client.ConnectSocket);
239 Debug.Assert(!remove);
240 _clientGroup.Add(client.ConnectSocket, client);
241 }
242
243 client.OnSocketClose += Client_OnSocketClose;
244 client.OnReadData += Client_OnReadData;
245 client.OnSendData += Client_OnSendData;
246
247 _listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read));
248
249 SocketEventParam param = new SocketEventParam(EN_SocketEvent.accept, client.ConnectSocket);
250 param.ClientInfo = client.ClientInfo;
251
252 _socketEventPool.PutObj(param);
253 }
254 catch (Exception ex)
255 {
256 NetLogger.Log(string.Format("Listener_OnAcceptSocket 异常 {0}***{1}", ex.Message, ex.StackTrace));
257 }
258 }
259
260
261 ObjectPoolWithEvent _listSendEvent = new ObjectPoolWithEvent();
262 private void NetSendProcess()
263 {
264 while (true)
265 {
266 DealSendEvent();
267 _listSendEvent.WaitOne(1000);
268 }
269 }
270
271 ObjectPoolWithEvent _listReadEvent = new ObjectPoolWithEvent();
272 private void NetReadProcess()
273 {
274 while (true)
275 {
276 DealReadEvent();
277 _listReadEvent.WaitOne(1000);
278 }
279 }
280
281
282 private void DealSendEvent()
283 {
284 while (true)
285 {
286 SocketEventDeal item = _listSendEvent.GetObj();
287 if (item == null)
288 break;
289 switch (item.SocketEvent)
290 {
291 case EN_SocketDealEvent.send:
292 {
293 while (true)
294 {
295 EN_SocketSendResult result = item.Client.SendNextData();
296 if (result == EN_SocketSendResult.HaveSend)
297 continue;
298 else
299 break;
300 }
301 }
302 break;
303 case EN_SocketDealEvent.read:
304 {
305 Debug.Assert(false);
306 }
307 break;
308 }
309 }
310 }
311
312 private void DealReadEvent()
313 {
314 while (true)
315 {
316 SocketEventDeal item = _listReadEvent.GetObj();
317 if (item == null)
318 break;
319 switch (item.SocketEvent)
320 {
321 case EN_SocketDealEvent.read:
322 {
323 while (true)
324 {
325 EN_SocketReadResult result = item.Client.ReadNextData();
326 if (result == EN_SocketReadResult.HaveRead)
327 continue;
328 else
329 break;
330 }
331 }
332 break;
333 case EN_SocketDealEvent.send:
334 {
335 Debug.Assert(false);
336 }
337 break;
338 }
339 }
340 }
341
342 private void Client_OnReadData(AsyncSocketClient client, byte[] readData)
343 {
344 //读下一条
345 _listReadEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.read));
346
347 try
348 {
349 SocketEventParam param = new SocketEventParam(EN_SocketEvent.read, client.ConnectSocket);
350 param.ClientInfo = client.ClientInfo;
351 param.Data = readData;
352 _socketEventPool.PutObj(param);
353
354 lock (this)
355 {
356 ReadByteCount += readData.Length;
357 }
358 }
359 catch (Exception ex)
360 {
361 NetLogger.Log(string.Format("Client_OnReadData 异常 {0}***{1}", ex.Message, ex.StackTrace));
362 }
363 }
364 #endregion
365
366 private void Client_OnSendData(AsyncSocketClient client, int sendCount)
367 {
368 //发送下一条
369 _listSendEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.send));
370 lock (this)
371 {
372 SendByteCount += sendCount;
373 }
374 }
375
376 private void Client_OnSocketClose(AsyncSocketClient client)
377 {
378 try
379 {
380 SocketEventParam param = new SocketEventParam(EN_SocketEvent.close, client.ConnectSocket);
381 param.ClientInfo = client.ClientInfo;
382 _socketEventPool.PutObj(param);
383 }
384 catch (Exception ex)
385 {
386 NetLogger.Log(string.Format("Client_OnSocketClose 异常 {0}***{1}", ex.Message, ex.StackTrace));
387 }
388 }
389
390 ///
391 /// 放到发送缓冲
392 ///
393 ///
394 ///
395 ///
396 public EN_SendDataResult SendData(Socket socket, byte[] data)
397 {
398 if (socket == null)
399 return EN_SendDataResult.no_client;
400 lock (_clientGroup)
401 {
402 if (!_clientGroup.ContainsKey(socket))
403 return EN_SendDataResult.no_client;
404 AsyncSocketClient client = _clientGroup[socket];
405 EN_SendDataResult result = client.PutSendData(data);
406 if (result == EN_SendDataResult.ok)
407 {
408 //发送下一条
409 _listSendEvent.PutObj(new SocketEventDeal(client, EN_SocketDealEvent.send));
410 }
411 return result;
412 }
413 }
414
415 ///
416 /// 设置某个连接的发送缓冲大小
417 ///
418 ///
419 ///
420 ///
421 public bool SetClientSendBuffer(Socket socket, int byteCount)
422 {
423 lock (_clientGroup)
424 {
425 if (!_clientGroup.ContainsKey(socket))
426 return false;
427 AsyncSocketClient client = _clientGroup[socket];
428 client.SendBufferByteCount = byteCount;
429 return true;
430 }
431 }
432
433
434 #region connect process
435 NetConnectManage _netConnectManage = new NetConnectManage();
436 ///
437 /// 异步连接一个客户端
438 ///
439 ///
440 ///
441 ///
442 ///
443 public bool ConnectAsyn(string peerIp, int peerPort, object tag)
444 {
445 return _netConnectManage.ConnectAsyn(peerIp, peerPort, tag);
446 }
447
448 ///
449 /// 同步连接一个客户端
450 ///
451 ///
452 ///
453 ///
454 ///
455 ///
456 public bool Connect(string peerIp, int peerPort, object tag, out Socket socket)
457 {
458 return _netConnectManage.Connect(peerIp, peerPort, tag, out socket);
459 }
460 #endregion
461 }
462
463 enum EN_SocketDealEvent
464 {
465 read,
466 send,
467 }
468 class SocketEventDeal
469 {
470 public AsyncSocketClient Client { get; set; }
471 public EN_SocketDealEvent SocketEvent { get; set; }
472 public SocketEventDeal(AsyncSocketClient client, EN_SocketDealEvent socketEvent)
473 {
474 Client = client;
475 SocketEvent = socketEvent;
476 }
477 }
478 }
View Code
使用起来非常简单,示例如下
1 using IocpCore;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Net.Sockets;
6 using System.Text;
7 using System.Threading.Tasks;
8 using System.Windows;
9
10 namespace WarningClient
11 {
12 public class SocketServer
13 {
14 public Action OnSocketEvent;
15
16 public Int64 SendByteCount
17 {
18 get
19 {
20 if (_netServer == null)
21 return 0;
22 return _netServer.SendByteCount;
23 }
24 }
25 public Int64 ReadByteCount
26 {
27 get
28 {
29 if (_netServer == null)
30 return 0;
31 return _netServer.ReadByteCount;
32 }
33 }
34
35 NetServer _netServer;
36 EN_PacketType _packetType = EN_PacketType.byteStream;
37 public void SetPacktType(EN_PacketType packetType)
38 {
39 _packetType = packetType;
40 if (_netServer == null)
41 return;
42 if (packetType == EN_PacketType.byteStream)
43 {
44 _netServer.SetPacketParam(0, 1024);
45 }
46 else
47 {
48 _netServer.SetPacketParam(9, 1024);
49 }
50 }
51
52 public bool Init(List listenPort)
53 {
54 NetLogger.OnLogEvent += NetLogger_OnLogEvent;
55 _netServer = new NetServer();
56 SetPacktType(_packetType);
57 _netServer.GetPacketTotalLen_Callback += GetPacketTotalLen;
58 _netServer.OnSocketPacketEvent += SocketPacketDeal;
59
60 foreach (int n in listenPort)
61 {
62 _netServer.AddListenPort(n, n);
63 }
64
65 List listenFault;
66 bool start = _netServer.StartListen(out listenFault);
67 return start;
68 }
69
70 int GetPacketTotalLen(byte[] data, int offset)
71 {
72 if (MainWindow._packetType == EN_PacketType.znss)
73 return GetPacketZnss(data, offset);
74 else
75 return GetPacketAnzhiyuan(data, offset);
76 }
77
78 int GetPacketAnzhiyuan(byte[] data, int offset)
79 {
80 int n = data[offset + 5] + 6;
81 return n;
82 }
83
84 int GetPacketZnss(byte[] data, int offset)
85 {
86 int packetLen = (int)(data[4]) + 5;
87 return packetLen;
88 }
89
90
91 public bool ConnectAsyn(string peerIp, int peerPort, object tag)
92 {
93 return _netServer.ConnectAsyn(peerIp, peerPort, tag);
94 }
95
96 public bool Connect(string peerIp, int peerPort, object tag, out Socket socket)
97 {
98 return _netServer.Connect(peerIp, peerPort, tag, out socket);
99 }
100
101 private void NetLogger_OnLogEvent(string message)
102 {
103 AppLog.Log(message);
104 }
105
106 Dictionary _clientGroup = new Dictionary();
107
108 public int ClientCount
109 {
110 get
111 {
112 lock (_clientGroup)
113 {
114 return _clientGroup.Count;
115 }
116 }
117 }
118 public List ClientList
119 {
120 get
121 {
122 if (_netServer != null)
123 return _netServer.ClientList;
124 return new List();
125 }
126 }
127 void AddClient(SocketEventParam socketParam)
128 {
129 lock (_clientGroup)
130 {
131 _clientGroup.Remove(socketParam.Socket);
132 _clientGroup.Add(socketParam.Socket, socketParam);
133 }
134 }
135
136 void RemoveClient(SocketEventParam socketParam)
137 {
138 lock (_clientGroup)
139 {
140 _clientGroup.Remove(socketParam.Socket);
141 }
142 }
143
144 ObjectPool _readDataPool = new ObjectPool();
145
146 public ObjectPool ReadDataPool
147 {
148 get
149 {
150 return _readDataPool;
151 }
152 }
153
154 private void SocketPacketDeal(SocketEventParam socketParam)
155 {
156 OnSocketEvent?.Invoke(socketParam);
157 if (socketParam.SocketEvent == EN_SocketEvent.read)
158 {
159 if (MainWindow._isShowReadPacket)
160 _readDataPool.PutObj(socketParam);
161 }
162 else if (socketParam.SocketEvent == EN_SocketEvent.accept)
163 {
164 AddClient(socketParam);
165 string peerIp = socketParam.ClientInfo.PeerIpPort;
166 AppLog.Log(string.Format("客户端链接!本地端口:{0},对端:{1}",
167 socketParam.ClientInfo.LocalPort, peerIp));
168 }
169 else if (socketParam.SocketEvent == EN_SocketEvent.connect)
170 {
171 string peerIp = socketParam.ClientInfo.PeerIpPort;
172 if (socketParam.Socket != null)
173 {
174 AddClient(socketParam);
175
176 AppLog.Log(string.Format("连接对端成功!本地端口:{0},对端:{1}",
177 socketParam.ClientInfo.LocalPort, peerIp));
178 }
179 else
180 {
181 AppLog.Log(string.Format("连接对端失败!本地端口:{0},对端:{1}",
182 socketParam.ClientInfo.LocalPort, peerIp));
183 }
184 }
185 else if (socketParam.SocketEvent == EN_SocketEvent.close)
186 {
187 MainWindow.MainWnd.OnSocketDisconnect(socketParam.Socket);
188 RemoveClient(socketParam);
189 string peerIp = socketParam.ClientInfo.PeerIpPort;
190 AppLog.Log(string.Format("客户端断开!本地端口:{0},对端:{1},",
191 socketParam.ClientInfo.LocalPort, peerIp));
192 }
193 }
194
195 public EN_SendDataResult SendData(Socket socket, byte[] data)
196 {
197 if(socket == null)
198 {
199 MessageBox.Show("还没连接!");
200 return EN_SendDataResult.no_client;
201 }
202 return _netServer.SendData(socket, data);
203 }
204
205 internal void SendToAll(byte[] data)
206 {
207 lock (_clientGroup)
208 {
209 foreach (Socket socket in _clientGroup.Keys)
210 {
211 SendData(socket, data);
212 }
213 }
214 }
215 }
216 }
View Code