无网不进  
软硬件开发

文章系列目录

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

用户状态封装类:

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