无网不进  
软硬件开发

文章系列目录

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

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

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

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

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

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

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

参考路径:

https://blog.csdn.net/zhujunxxxxx/article/details/44258719

代码下载地址

http://download.csdn.net/detail/zhujunxxxxx/8510991

本文介绍
在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现。System.Net 命名空间中的所有其他网络访问类都建立在该套接字Socket实现之上,如TCPClient、TCPListener 和 UDPClient 类封装有关创建到 Internet 的 TCP 和 UDP 连接的详细信息;NetworkStream类则提供用于网络访问的基础数据流等,常见的许多Internet服务都可以见到Socket的踪影,如Telnet、Http、Email、Echo等,这些服务尽管通讯协议Protocol的定义不同,但是其基础的传输都是采用的Socket。 其实,Socket可以象流Stream一样被视为一个数据通道,这个通道架设在应用程序端(客户端)和远程服务器端之间,而后,数据的读取(接收)和写入(发送)均针对这个通道来进行。 可见,在应用程序端或者服务器端创建了Socket对象之后,就可以使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据; 针对Socket编程,.NET 框架的 Socket 类是 Winsock32 API 提供的套接字服务的托管代码版本。其中为实现网络编程提供了大量的方法,大多数情况下,Socket 类方法只是将数据封送到它们的本机 Win32 副本中并处理任何必要的安全检查。如果你熟悉Winsock API函数,那么用Socket类编写网络程序会非常容易,当然,如果你不曾接触过,也不会太困难,跟随下面的解说,你会发觉使用Socket类开发windows
 网络应用程序原来有规可寻,它们在大多数情况下遵循大致相同的步骤。
本节介绍使用Socket来实现一个高性能的异步UDP服务器,实际上UDP是不分客户机和服务器的,但是我们有的时候和服务器通讯就是使用UDP来进行的。
Socket异步UDP服务器:

  1 using System;
  2 
  3 using System.Collections.Generic;
  4 
  5 using System.Linq;
  6 
  7 using System.Text;
  8 
  9 using System.Net;
 10 
 11 using System.Net.Sockets;
 12 
 13  
 14 
 15 namespace NetFrame.Net.UDP.Sock.Asynchronous
 16 
 17 {
 18 
 19     /// <summary>
 20 
 21     /// SOCKET实现异步UDP服务器
 22 
 23     /// </summary>
 24 
 25     public class AsyncSocketUDPServer
 26 
 27     {
 28 
 29         #region Fields
 30 
 31         /// <summary>
 32 
 33         /// 服务器程序允许的最大客户端连接数
 34 
 35         /// </summary>
 36 
 37         private int _maxClient;
 38 
 39  
 40 
 41         /// <summary>
 42 
 43         /// 当前的连接的客户端数
 44 
 45         /// </summary>
 46 
 47         //private int _clientCount;
 48 
 49  
 50 
 51         /// <summary>
 52 
 53         /// 服务器使用的同步socket
 54 
 55         /// </summary>
 56 
 57         private Socket _serverSock;
 58 
 59  
 60 
 61         /// <summary>
 62 
 63         /// 客户端会话列表
 64 
 65         /// </summary>
 66 
 67         //private List<AsyncUDPSocketState> _clients;
 68 
 69  
 70 
 71         private bool disposed = false;
 72 
 73  
 74 
 75         /// <summary>
 76 
 77         /// 数据接受缓冲区
 78 
 79         /// </summary>
 80 
 81         private byte[] _recvBuffer;
 82 
 83  
 84 
 85         #endregion
 86 
 87  
 88 
 89         #region Properties
 90 
 91  
 92 
 93         /// <summary>
 94 
 95         /// 服务器是否正在运行
 96 
 97         /// </summary>
 98 
 99         public bool IsRunning { get; private set; }
100 
101         /// <summary>
102 
103         /// 监听的IP地址
104 
105         /// </summary>
106 
107         public IPAddress Address { get; private set; }
108 
109         /// <summary>
110 
111         /// 监听的端口
112 
113         /// </summary>
114 
115         public int Port { get; private set; }
116 
117         /// <summary>
118 
119         /// 通信使用的编码
120 
121         /// </summary>
122 
123         public Encoding Encoding { get; set; }
124 
125  
126 
127         #endregion
128 
129  
130 
131         #region 构造函数
132 
133  
134 
135         /// <summary>
136 
137         /// 异步Socket UDP服务器
138 
139         /// </summary>
140 
141         /// <param name="listenPort">监听的端口</param>
142 
143         public AsyncSocketUDPServer(int listenPort)
144 
145             : this(IPAddress.Any, listenPort,1024)
146 
147         {
148 
149         }
150 
151  
152 
153         /// <summary>
154 
155         /// 异步Socket UDP服务器
156 
157         /// </summary>
158 
159         /// <param name="localEP">监听的终结点</param>
160 
161         public AsyncSocketUDPServer(IPEndPoint localEP)
162 
163             : this(localEP.Address, localEP.Port,1024)
164 
165         {
166 
167         }
168 
169  
170 
171         /// <summary>
172 
173         /// 异步Socket UDP服务器
174 
175         /// </summary>
176 
177         /// <param name="localIPAddress">监听的IP地址</param>
178 
179         /// <param name="listenPort">监听的端口</param>
180 
181         /// <param name="maxClient">最大客户端数量</param>
182 
183         public AsyncSocketUDPServer(IPAddress localIPAddress, int listenPort, int maxClient)
184 
185         {
186 
187             this.Address = localIPAddress;
188 
189             this.Port = listenPort;
190 
191             this.Encoding = Encoding.Default;
192 
193  
194 
195             _maxClient = maxClient;
196 
197             //_clients = new List<AsyncUDPSocketState>();
198 
199             _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
200 
201  
202 
203             _recvBuffer=new byte[_serverSock.ReceiveBufferSize];
204 
205         }
206 
207  
208 
209         #endregion
210 
211  
212 
213         #region Method
214 
215         /// <summary>
216 
217         /// 启动服务器
218 
219         /// </summary>
220 
221         /// <returns>异步TCP服务器</returns>
222 
223         public void Start()
224 
225         {
226 
227             if (!IsRunning)
228 
229             {
230 
231                 IsRunning = true;
232 
233                 _serverSock.Bind(new IPEndPoint(this.Address, this.Port));
234 
235                 //_serverSock.Connect(new IPEndPoint(IPAddress.Any, 0));
236 
237  
238 
239                 AsyncSocketUDPState so = new AsyncSocketUDPState();
240 
241                 so.workSocket = _serverSock;
242 
243  
244 
245                 _serverSock.BeginReceiveFrom(so.buffer, 0, so.buffer.Length, SocketFlags.None,
246 
247                     ref so.remote, new AsyncCallback(ReceiveDataAsync), null);
248 
249  
250 
251  
252 
253                 //EndPoint sender = new IPEndPoint(IPAddress.Any, 0);
254 
255  
256 
257                 //_serverSock.BeginReceiveFrom(_recvBuffer, 0, _recvBuffer.Length, SocketFlags.None,
258 
259                 //    ref sender, new AsyncCallback(ReceiveDataAsync), sender);
260 
261  
262 
263                 //BeginReceive 和 BeginReceiveFrom的区别是什么
264 
265                 /*_serverSock.BeginReceive(_recvBuffer, 0, _recvBuffer.Length, SocketFlags.None,
266 
267                     new AsyncCallback(ReceiveDataAsync), null);*/
268 
269             }
270 
271         }
272 
273  
274 
275         /// <summary>
276 
277         /// 停止服务器
278 
279         /// </summary>
280 
281         public void Stop()
282 
283         {
284 
285             if (IsRunning)
286 
287             {
288 
289                 IsRunning = false;
290 
291                 _serverSock.Close();
292 
293                 //TODO 关闭对所有客户端的连接
294 
295  
296 
297             }
298 
299         }
300 
301  
302 
303         /// <summary>
304 
305         /// 接收数据的方法
306 
307         /// </summary>
308 
309         /// <param name="ar"></param>
310 
311         private void ReceiveDataAsync(IAsyncResult ar)
312 
313         {
314 
315             AsyncSocketUDPState so = ar.AsyncState as AsyncSocketUDPState;
316 
317             //EndPoint sender = new IPEndPoint(IPAddress.Any, 0);
318 
319             int len = -1;
320 
321             try
322 
323             {
324 
325                 len = _serverSock.EndReceiveFrom(ar, ref so.remote);
326 
327  
328 
329                 //len = _serverSock.EndReceiveFrom(ar, ref sender);
330 
331  
332 
333                 //EndReceiveFrom 和 EndReceive区别
334 
335                 //len = _serverSock.EndReceive(ar);
336 
337                 //TODO 处理数据
338 
339  
340 
341                 //触发数据收到事件
342 
343                 RaiseDataReceived(so);
344 
345             }
346 
347             catch (Exception)
348 
349             {
350 
351                 //TODO 处理异常
352 
353                 RaiseOtherException(so);
354 
355             }
356 
357             finally
358 
359             {
360 
361                 if (IsRunning && _serverSock != null)
362 
363                     _serverSock.BeginReceiveFrom(so.buffer, 0, so.buffer.Length, SocketFlags.None,
364 
365                 ref so.remote, new AsyncCallback(ReceiveDataAsync), so);
366 
367             }
368 
369         }
370 
371         /// <summary>
372 
373         /// 发送数据
374 
375         /// </summary>
376 
377         /// <param name="msg"></param>
378 
379         /// <param name="remote"></param>
380 
381         public void Send(string msg,EndPoint remote)
382 
383         {
384 
385             byte[] data = Encoding.Default.GetBytes(msg);
386 
387             try
388 
389             {
390 
391                 RaisePrepareSend(null);
392 
393                 _serverSock.BeginSendTo(data, 0, data.Length, SocketFlags.None, remote, new AsyncCallback(SendDataEnd), _serverSock);
394 
395             }
396 
397             catch (Exception)
398 
399             {
400 
401                 //TODO 异常处理
402 
403                 RaiseOtherException(null);
404 
405             }
406 
407         }
408 
409  
410 
411         private void SendDataEnd(IAsyncResult ar)
412 
413         {
414 
415             ((Socket)ar.AsyncState).EndSendTo(ar);
416 
417             RaiseCompletedSend(null);
418 
419         }
420 
421  
422 
423         #endregion
424 
425  
426 
427         #region 事件
428 
429         /// <summary>
430 
431         /// 接收到数据事件
432 
433         /// </summary>
434 
435         public event EventHandler<AsyncSocketUDPEventArgs> DataReceived;
436 
437  
438 
439         private void RaiseDataReceived(AsyncSocketUDPState state)
440 
441         {
442 
443             if (DataReceived != null)
444 
445             {
446 
447                 DataReceived(this, new AsyncSocketUDPEventArgs(state));
448 
449             }
450 
451         }
452 
453  
454 
455         /// <summary>
456 
457         /// 发送数据前的事件
458 
459         /// </summary>
460 
461         public event EventHandler<AsyncSocketUDPEventArgs> PrepareSend;
462 
463  
464 
465         /// <summary>
466 
467         /// 触发发送数据前的事件
468 
469         /// </summary>
470 
471         /// <param name="state"></param>
472 
473         private void RaisePrepareSend(AsyncSocketUDPState state)
474 
475         {
476 
477             if (PrepareSend != null)
478 
479             {
480 
481                 PrepareSend(this, new AsyncSocketUDPEventArgs(state));
482 
483             }
484 
485         }
486 
487  
488 
489         /// <summary>
490 
491         /// 数据发送完毕事件
492 
493         /// </summary>
494 
495         public event EventHandler<AsyncSocketUDPEventArgs> CompletedSend;
496 
497  
498 
499         /// <summary>
500 
501         /// 触发数据发送完毕的事件
502 
503         /// </summary>
504 
505         /// <param name="state"></param>
506 
507         private void RaiseCompletedSend(AsyncSocketUDPState state)
508 
509         {
510 
511             if (CompletedSend != null)
512 
513             {
514 
515                 CompletedSend(this, new AsyncSocketUDPEventArgs(state));
516 
517             }
518 
519         }
520 
521  
522 
523         /// <summary>
524 
525         /// 网络错误事件
526 
527         /// </summary>
528 
529         public event EventHandler<AsyncSocketUDPEventArgs> NetError;
530 
531         /// <summary>
532 
533         /// 触发网络错误事件
534 
535         /// </summary>
536 
537         /// <param name="state"></param>
538 
539         private void RaiseNetError(AsyncSocketUDPState state)
540 
541         {
542 
543             if (NetError != null)
544 
545             {
546 
547                 NetError(this, new AsyncSocketUDPEventArgs(state));
548 
549             }
550 
551         }
552 
553  
554 
555         /// <summary>
556 
557         /// 异常事件
558 
559         /// </summary>
560 
561         public event EventHandler<AsyncSocketUDPEventArgs> OtherException;
562 
563         /// <summary>
564 
565         /// 触发异常事件
566 
567         /// </summary>
568 
569         /// <param name="state"></param>
570 
571         private void RaiseOtherException(AsyncSocketUDPState state, string descrip)
572 
573         {
574 
575             if (OtherException != null)
576 
577             {
578 
579                 OtherException(this, new AsyncSocketUDPEventArgs(descrip, state));
580 
581             }
582 
583         }
584 
585         private void RaiseOtherException(AsyncSocketUDPState state)
586 
587         {
588 
589             RaiseOtherException(state, "");
590 
591         }
592 
593         #endregion
594 
595  
596 
597         #region Close
598 
599         /// <summary>
600 
601         /// 关闭一个与客户端之间的会话
602 
603         /// </summary>
604 
605         /// <param name="state">需要关闭的客户端会话对象</param>
606 
607         public void Close(AsyncSocketUDPState state)
608 
609         {
610 
611             if (state != null)
612 
613             {
614 
615                 //_clients.Remove(state);
616 
617                 //_clientCount--;
618 
619                 //TODO 触发关闭事件
620 
621             }
622 
623         }
624 
625         /// <summary>
626 
627         /// 关闭所有的客户端会话,与所有的客户端连接会断开
628 
629         /// </summary>
630 
631         public void CloseAllClient()
632 
633         {
634 
635             //foreach (AsyncUDPSocketState client in _clients)
636 
637             //{
638 
639             //    Close(client);
640 
641             //}
642 
643             //_clientCount = 0;
644 
645             //_clients.Clear();
646 
647         }
648 
649  
650 
651         #endregion
652 
653  
654 
655         #region 释放
656 
657         /// <summary>
658 
659         /// Performs application-defined tasks associated with freeing, 
660 
661         /// releasing, or resetting unmanaged resources.
662 
663         /// </summary>
664 
665         public void Dispose()
666 
667         {
668 
669             Dispose(true);
670 
671             GC.SuppressFinalize(this);
672 
673         }
674 
675  
676 
677         /// <summary>
678 
679         /// Releases unmanaged and - optionally - managed resources
680 
681         /// </summary>
682 
683         /// <param name="disposing"><c>true</c> to release 
684 
685         /// both managed and unmanaged resources; <c>false</c> 
686 
687         /// to release only unmanaged resources.</param>
688 
689         protected virtual void Dispose(bool disposing)
690 
691         {
692 
693             if (!this.disposed)
694 
695             {
696 
697                 if (disposing)
698 
699                 {
700 
701                     try
702 
703                     {
704 
705                         Stop();
706 
707                         if (_serverSock != null)
708 
709                         {
710 
711                             _serverSock = null;
712 
713                         }
714 
715                     }
716 
717                     catch (SocketException)
718 
719                     {
720 
721                         //TODO
722 
723                         RaiseOtherException(null);
724 
725                     }
726 
727                 }
728 
729                 disposed = true;
730 
731             }
732 
733         }
734 
735         #endregion
736 
737     }
738 
739 }

会话封装类:

 1 using System;
 2 
 3 using System.Collections.Generic;
 4 
 5 using System.Linq;
 6 
 7 using System.Text;
 8 
 9 using System.Net;
10 
11 using System.Net.Sockets;
12 
13  
14 
15 namespace NetFrame.Net.UDP.Sock.Asynchronous
16 
17 {
18 
19     public class AsyncSocketUDPState
20 
21     {
22 
23         // Client   socket.
24 
25         public Socket workSocket = null;
26 
27         // Size of receive buffer.
28 
29         public const int BufferSize = 1024;
30 
31         // Receive buffer.
32 
33         public byte[] buffer = new byte[BufferSize];
34 
35         // Received data string.
36 
37         public StringBuilder sb = new StringBuilder();
38 
39  
40 
41         public EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
42 
43     }
44 
45 }

Socket异步UDP服务器事件参数类:

 1 using System;
 2 
 3 using System.Collections.Generic;
 4 
 5 using System.Linq;
 6 
 7 using System.Text;
 8 
 9  
10 
11 namespace NetFrame.Net.UDP.Sock.Asynchronous
12 
13 {
14 
15     /// <summary>
16 
17     /// SOCKET 异步UDP 事件类
18 
19     /// </summary>
20 
21     public class AsyncSocketUDPEventArgs : EventArgs
22 
23     {
24 
25         /// <summary>
26 
27         /// 提示信息
28 
29         /// </summary>
30 
31         public string _msg;
32 
33  
34 
35         /// <summary>
36 
37         /// 客户端状态封装类
38 
39         /// </summary>
40 
41         public AsyncSocketUDPState _state;
42 
43  
44 
45         /// <summary>
46 
47         /// 是否已经处理过了
48 
49         /// </summary>
50 
51         public bool IsHandled { get; set; }
52 
53  
54 
55         public AsyncSocketUDPEventArgs(string msg)
56 
57         {
58 
59             this._msg = msg;
60 
61             IsHandled = false;
62 
63         }
64 
65         public AsyncSocketUDPEventArgs(AsyncSocketUDPState state)
66 
67         {
68 
69             this._state = state;
70 
71             IsHandled = false;
72 
73         }
74 
75         public AsyncSocketUDPEventArgs(string msg, AsyncSocketUDPState state)
76 
77         {
78 
79             this._msg = msg;
80 
81             this._state = state;
82 
83             IsHandled = false;
84 
85         }
86 
87     }
88 
89 }

 

posted on 2019-01-23 11:41  无网不进  阅读(1051)  评论(0)    收藏  举报