无网不进  
软硬件开发

文章系列目录

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

本文介绍
UdpClient 类在同步阻塞模式中为发送和接收无连接的 UDP 数据包而提供了简单的方法。因为 UDP 是一种无连接的传输协议,所以你不需要在发送和接收数据之前建立任何远程主机连接。你只需要按照下列方式来建立默认的远程主机选项:
使用远程主机名称和端口号作为参数来创建 UdpClient 类的实例。
创建 UdpClient 类的实例然后调用 Connect 方法。
你可以使用任何由 UdpClient 所提供的发送方法把数据发送给远程设备。然后使用 Receive 方法来接收来自于远程主机的数据。
提示:如果你已经指定了一个默认的远程主机,就不要使用主机名称或者 IPEndPoint 来调用 Send 方法。如果你这样做,那么 UdpClient 将会抛出一个异常。
UdpClient 方法同样允许你发送和接收多点传送的数据包。而使用 JoinMulticastGroup 方法可以把 UdpClient 订阅到多点传送分组。也可以使用 DropMulticastGroup 方法把 UdpClient 从多点传送分组的订阅中取消。
本节介绍使用UdpClient实现一个异步的高性能UDP服务器
UdpClient异步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.Sockets;
 10 
 11 using System.Net;
 12 
 13  
 14 
 15 namespace NetFrame.Net.UDP.Listener.Asynchronous
 16 
 17 {
 18 
 19     /// <summary>
 20 
 21     /// UdpClient 实现异步UDP服务器
 22 
 23     /// </summary>
 24 
 25     public class AsyncUDPServer
 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         /// 服务器使用的异步UdpClient
 54 
 55         /// </summary>
 56 
 57         private UdpClient _server;
 58 
 59  
 60 
 61         /// <summary>
 62 
 63         /// 客户端会话列表
 64 
 65         /// </summary>
 66 
 67         //private List<AsyncUDPState> _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         /// 异步UdpClient UDP服务器
138 
139         /// </summary>
140 
141         /// <param name="listenPort">监听的端口</param>
142 
143         public AsyncUDPServer(int listenPort)
144 
145             : this(IPAddress.Any, listenPort,1024)
146 
147         {
148 
149         }
150 
151  
152 
153         /// <summary>
154 
155         /// 异步UdpClient UDP服务器
156 
157         /// </summary>
158 
159         /// <param name="localEP">监听的终结点</param>
160 
161         public AsyncUDPServer(IPEndPoint localEP)
162 
163             : this(localEP.Address, localEP.Port,1024)
164 
165         {
166 
167         }
168 
169  
170 
171         /// <summary>
172 
173         /// 异步UdpClient 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 AsyncUDPServer(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             _server = new UdpClient(new IPEndPoint(this.Address, this.Port));
200 
201  
202 
203             _recvBuffer=new byte[_server.Client.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                 _server.EnableBroadcast = true;
234 
235                 _server.BeginReceive(ReceiveDataAsync, null);
236 
237             }
238 
239         }
240 
241  
242 
243         /// <summary>
244 
245         /// 停止服务器
246 
247         /// </summary>
248 
249         public void Stop()
250 
251         {
252 
253             if (IsRunning)
254 
255             {
256 
257                 IsRunning = false;
258 
259                 _server.Close();
260 
261                 //TODO 关闭对所有客户端的连接
262 
263  
264 
265             }
266 
267         }
268 
269  
270 
271         /// <summary>
272 
273         /// 接收数据的方法
274 
275         /// </summary>
276 
277         /// <param name="ar"></param>
278 
279         private void ReceiveDataAsync(IAsyncResult ar)
280 
281         {
282 
283             IPEndPoint remote=null;
284 
285             byte[] buffer = null;
286 
287             try
288 
289             {
290 
291                 buffer = _server.EndReceive(ar, ref remote);
292 
293  
294 
295                 //触发数据收到事件
296 
297                 RaiseDataReceived(null);
298 
299             }
300 
301             catch (Exception)
302 
303             {
304 
305                 //TODO 处理异常
306 
307                 RaiseOtherException(null);
308 
309             }
310 
311             finally
312 
313             {
314 
315                 if (IsRunning && _server != null)
316 
317                     _server.BeginReceive(ReceiveDataAsync, null);
318 
319             }
320 
321         }
322 
323  
324 
325         /// <summary>
326 
327         /// 发送数据
328 
329         /// </summary>
330 
331         /// <param name="msg"></param>
332 
333         /// <param name="remote"></param>
334 
335         public void Send(string msg, IPEndPoint remote)
336 
337         {
338 
339             byte[] data = Encoding.Default.GetBytes(msg);
340 
341             try
342 
343             {
344 
345                 RaisePrepareSend(null);
346 
347                 _server.BeginSend(data, data.Length, new AsyncCallback(SendCallback), null);
348 
349             }
350 
351             catch (Exception)
352 
353             {
354 
355                 //TODO 异常处理
356 
357                 RaiseOtherException(null);
358 
359             }
360 
361         }
362 
363  
364 
365         private void SendCallback(IAsyncResult ar)
366 
367         {
368 
369             if (ar.IsCompleted)
370 
371             {
372 
373                 try
374 
375                 {
376 
377                     _server.EndSend(ar);
378 
379                     //消息发送完毕事件
380 
381                     RaiseCompletedSend(null);
382 
383                 }
384 
385                 catch (Exception)
386 
387                 {
388 
389                     //TODO 数据发送失败事件
390 
391                     RaiseOtherException(null);
392 
393                 }
394 
395             }
396 
397  
398 
399         }
400 
401         #endregion
402 
403  
404 
405         #region 事件
406 
407         /// <summary>
408 
409         /// 接收到数据事件
410 
411         /// </summary>
412 
413         public event EventHandler<AsyncUDPEventArgs> DataReceived;
414 
415  
416 
417         private void RaiseDataReceived(AsyncUDPState state)
418 
419         {
420 
421             if (DataReceived != null)
422 
423             {
424 
425                 DataReceived(this, new AsyncUDPEventArgs(state));
426 
427             }
428 
429         }
430 
431  
432 
433         /// <summary>
434 
435         /// 发送数据前的事件
436 
437         /// </summary>
438 
439         public event EventHandler<AsyncUDPEventArgs> PrepareSend;
440 
441  
442 
443         /// <summary>
444 
445         /// 触发发送数据前的事件
446 
447         /// </summary>
448 
449         /// <param name="state"></param>
450 
451         private void RaisePrepareSend(AsyncUDPState state)
452 
453         {
454 
455             if (PrepareSend != null)
456 
457             {
458 
459                 PrepareSend(this, new AsyncUDPEventArgs(state));
460 
461             }
462 
463         }
464 
465  
466 
467         /// <summary>
468 
469         /// 数据发送完毕事件
470 
471         /// </summary>
472 
473         public event EventHandler<AsyncUDPEventArgs> CompletedSend;
474 
475  
476 
477         /// <summary>
478 
479         /// 触发数据发送完毕的事件
480 
481         /// </summary>
482 
483         /// <param name="state"></param>
484 
485         private void RaiseCompletedSend(AsyncUDPState state)
486 
487         {
488 
489             if (CompletedSend != null)
490 
491             {
492 
493                 CompletedSend(this, new AsyncUDPEventArgs(state));
494 
495             }
496 
497         }
498 
499  
500 
501         /// <summary>
502 
503         /// 网络错误事件
504 
505         /// </summary>
506 
507         public event EventHandler<AsyncUDPEventArgs> NetError;
508 
509         /// <summary>
510 
511         /// 触发网络错误事件
512 
513         /// </summary>
514 
515         /// <param name="state"></param>
516 
517         private void RaiseNetError(AsyncUDPState state)
518 
519         {
520 
521             if (NetError != null)
522 
523             {
524 
525                 NetError(this, new AsyncUDPEventArgs(state));
526 
527             }
528 
529         }
530 
531  
532 
533         /// <summary>
534 
535         /// 异常事件
536 
537         /// </summary>
538 
539         public event EventHandler<AsyncUDPEventArgs> OtherException;
540 
541         /// <summary>
542 
543         /// 触发异常事件
544 
545         /// </summary>
546 
547         /// <param name="state"></param>
548 
549         private void RaiseOtherException(AsyncUDPState state, string descrip)
550 
551         {
552 
553             if (OtherException != null)
554 
555             {
556 
557                 OtherException(this, new AsyncUDPEventArgs(descrip, state));
558 
559             }
560 
561         }
562 
563         private void RaiseOtherException(AsyncUDPState state)
564 
565         {
566 
567             RaiseOtherException(state, "");
568 
569         }
570 
571         #endregion
572 
573  
574 
575         #region Close
576 
577         /// <summary>
578 
579         /// 关闭一个与客户端之间的会话
580 
581         /// </summary>
582 
583         /// <param name="state">需要关闭的客户端会话对象</param>
584 
585         public void Close(AsyncUDPState state)
586 
587         {
588 
589             if (state != null)
590 
591             {
592 
593                 //_clients.Remove(state);
594 
595                 //_clientCount--;
596 
597                 //TODO 触发关闭事件
598 
599             }
600 
601         }
602 
603         /// <summary>
604 
605         /// 关闭所有的客户端会话,与所有的客户端连接会断开
606 
607         /// </summary>
608 
609         public void CloseAllClient()
610 
611         {
612 
613             //foreach (AsyncUDPSocketState client in _clients)
614 
615             //{
616 
617             //    Close(client);
618 
619             //}
620 
621             //_clientCount = 0;
622 
623             //_clients.Clear();
624 
625         }
626 
627  
628 
629         #endregion
630 
631  
632 
633         #region 释放
634 
635         /// <summary>
636 
637         /// Performs application-defined tasks associated with freeing, 
638 
639         /// releasing, or resetting unmanaged resources.
640 
641         /// </summary>
642 
643         public void Dispose()
644 
645         {
646 
647             Dispose(true);
648 
649             GC.SuppressFinalize(this);
650 
651         }
652 
653  
654 
655         /// <summary>
656 
657         /// Releases unmanaged and - optionally - managed resources
658 
659         /// </summary>
660 
661         /// <param name="disposing"><c>true</c> to release 
662 
663         /// both managed and unmanaged resources; <c>false</c> 
664 
665         /// to release only unmanaged resources.</param>
666 
667         protected virtual void Dispose(bool disposing)
668 
669         {
670 
671             if (!this.disposed)
672 
673             {
674 
675                 if (disposing)
676 
677                 {
678 
679                     try
680 
681                     {
682 
683                         Stop();
684 
685                         if (_server != null)
686 
687                         {
688 
689                             _server = null;
690 
691                         }
692 
693                     }
694 
695                     catch (SocketException)
696 
697                     {
698 
699                         //TODO
700 
701                         RaiseOtherException(null);
702 
703                     }
704 
705                 }
706 
707                 disposed = true;
708 
709             }
710 
711         }
712 
713         #endregion
714 
715     }
716 
717 }

 

客户端信息封装了类:

 1 using System;
 2 
 3 using System.Collections.Generic;
 4 
 5 using System.Linq;
 6 
 7 using System.Text;
 8 
 9 using System.Net.Sockets;
10 
11 using System.Net;
12 
13  
14 
15 namespace NetFrame.Net.UDP.Listener.Asynchronous
16 
17 {
18 
19     public class AsyncUDPState
20 
21     {
22 
23         // Client   socket.
24 
25         public UdpClient udpClient = 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 IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
42 
43     }
44 
45 }

服务器事件参数类:

 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.Listener.Asynchronous
12 
13 {
14 
15     /// <summary>
16 
17     /// UdpClient 异步UDP服务器事件参数类
18 
19     /// </summary>
20 
21     public class AsyncUDPEventArgs : 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 AsyncUDPState _state;
42 
43  
44 
45         /// <summary>
46 
47         /// 是否已经处理过了
48 
49         /// </summary>
50 
51         public bool IsHandled { get; set; }
52 
53  
54 
55         public AsyncUDPEventArgs(string msg)
56 
57         {
58 
59             this._msg = msg;
60 
61             IsHandled = false;
62 
63         }
64 
65         public AsyncUDPEventArgs(AsyncUDPState state)
66 
67         {
68 
69             this._state = state;
70 
71             IsHandled = false;
72 
73         }
74 
75         public AsyncUDPEventArgs(string msg, AsyncUDPState 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:46  无网不进  阅读(789)  评论(0)    收藏  举报