无网不进  
软硬件开发

文章系列目录

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服务器。
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.Sockets;
 10 
 11 using System.Net;
 12 
 13 using System.Threading;
 14 
 15  
 16 
 17 namespace NetFrame.Net.UDP.Sock.Synchronous
 18 
 19 {
 20 
 21     /// <summary>
 22 
 23     /// Socket 实现同步UDP服务器
 24 
 25     /// </summary>
 26 
 27     public class SocketUDPServer
 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         /// 服务器使用的同步socket
 56 
 57         /// </summary>
 58 
 59         private Socket _serverSock;
 60 
 61  
 62 
 63         /// <summary>
 64 
 65         /// 客户端会话列表
 66 
 67         /// </summary>
 68 
 69         private List<SocketUDPState> _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         /// 异步Socket UDP服务器
140 
141         /// </summary>
142 
143         /// <param name="listenPort">监听的端口</param>
144 
145         public SocketUDPServer(int listenPort)
146 
147             : this(IPAddress.Any, listenPort,1024)
148 
149         {
150 
151         }
152 
153  
154 
155         /// <summary>
156 
157         /// 异步Socket UDP服务器
158 
159         /// </summary>
160 
161         /// <param name="localEP">监听的终结点</param>
162 
163         public SocketUDPServer(IPEndPoint localEP)
164 
165             : this(localEP.Address, localEP.Port,1024)
166 
167         {
168 
169         }
170 
171  
172 
173         /// <summary>
174 
175         /// 异步Socket 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 SocketUDPServer(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<SocketUDPState>();
200 
201             _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
202 
203  
204 
205             _recvBuffer=new byte[_serverSock.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                 _serverSock.Bind(new IPEndPoint(this.Address, this.Port));
236 
237                 //启动一个线程监听数据
238 
239                 new Thread(ReceiveData).Start();
240 
241             }
242 
243         }
244 
245  
246 
247         /// <summary>
248 
249         /// 停止服务器
250 
251         /// </summary>
252 
253         public void Stop()
254 
255         {
256 
257             if (IsRunning)
258 
259             {
260 
261                 IsRunning = false;
262 
263                 _serverSock.Close();
264 
265                 //TODO 关闭对所有客户端的连接
266 
267                 CloseAllClient();
268 
269             }
270 
271         }
272 
273  
274 
275         /// <summary>
276 
277         /// 同步数据接收方法
278 
279         /// </summary>
280 
281         private void ReceiveData()
282 
283         {
284 
285             int len = -1;
286 
287             EndPoint remote = null;
288 
289             while (true)
290 
291             {
292 
293                 try
294 
295                 {
296 
297                     len = _serverSock.ReceiveFrom(_recvBuffer, ref remote);
298 
299  
300 
301                     //if (!_clients.Contains(remote))
302 
303                     //{
304 
305                     //    _clients.Add(remote);
306 
307                     //}
308 
309                 }
310 
311                 catch (Exception)
312 
313                 {
314 
315                     //TODO 异常处理操作
316 
317                     RaiseOtherException(null);
318 
319                 }
320 
321             }
322 
323         }
324 
325         /// <summary>
326 
327         /// 同步发送数据
328 
329         /// </summary>
330 
331         public void Send(string msg, EndPoint clientip)
332 
333         {
334 
335             byte[] data = Encoding.Default.GetBytes(msg);
336 
337             try
338 
339             {
340 
341                 _serverSock.SendTo(data, clientip);
342 
343                 //数据发送完成事件
344 
345                 RaiseCompletedSend(null);
346 
347             }
348 
349             catch (Exception)
350 
351             {
352 
353                 //TODO 异常处理
354 
355                 RaiseOtherException(null);
356 
357             }
358 
359         }
360 
361  
362 
363         #endregion
364 
365  
366 
367         #region 事件
368 
369         /// <summary>
370 
371         /// 接收到数据事件
372 
373         /// </summary>
374 
375         public event EventHandler<SocketUDPEventArgs> DataReceived;
376 
377  
378 
379         private void RaiseDataReceived(SocketUDPState state)
380 
381         {
382 
383             if (DataReceived != null)
384 
385             {
386 
387                 DataReceived(this, new SocketUDPEventArgs(state));
388 
389             }
390 
391         }
392 
393  
394 
395         /// <summary>
396 
397         /// 数据发送完毕事件
398 
399         /// </summary>
400 
401         public event EventHandler<SocketUDPEventArgs> CompletedSend;
402 
403  
404 
405         /// <summary>
406 
407         /// 触发数据发送完毕的事件
408 
409         /// </summary>
410 
411         /// <param name="state"></param>
412 
413         private void RaiseCompletedSend(SocketUDPState state)
414 
415         {
416 
417             if (CompletedSend != null)
418 
419             {
420 
421                 CompletedSend(this, new SocketUDPEventArgs(state));
422 
423             }
424 
425         }
426 
427  
428 
429         /// <summary>
430 
431         /// 网络错误事件
432 
433         /// </summary>
434 
435         public event EventHandler<SocketUDPEventArgs> NetError;
436 
437         /// <summary>
438 
439         /// 触发网络错误事件
440 
441         /// </summary>
442 
443         /// <param name="state"></param>
444 
445         private void RaiseNetError(SocketUDPState state)
446 
447         {
448 
449             if (NetError != null)
450 
451             {
452 
453                 NetError(this, new SocketUDPEventArgs(state));
454 
455             }
456 
457         }
458 
459  
460 
461         /// <summary>
462 
463         /// 异常事件
464 
465         /// </summary>
466 
467         public event EventHandler<SocketUDPEventArgs> OtherException;
468 
469         /// <summary>
470 
471         /// 触发异常事件
472 
473         /// </summary>
474 
475         /// <param name="state"></param>
476 
477         private void RaiseOtherException(SocketUDPState state, string descrip)
478 
479         {
480 
481             if (OtherException != null)
482 
483             {
484 
485                 OtherException(this, new SocketUDPEventArgs(descrip, state));
486 
487             }
488 
489         }
490 
491         private void RaiseOtherException(SocketUDPState state)
492 
493         {
494 
495             RaiseOtherException(state, "");
496 
497         }
498 
499         #endregion
500 
501  
502 
503         #region Close
504 
505         /// <summary>
506 
507         /// 关闭一个与客户端之间的会话
508 
509         /// </summary>
510 
511         /// <param name="state">需要关闭的客户端会话对象</param>
512 
513         public void Close(SocketUDPState state)
514 
515         {
516 
517             if (state != null)
518 
519             {
520 
521                 _clients.Remove(state);
522 
523                 _clientCount--;
524 
525                 //TODO 触发关闭事件
526 
527             }
528 
529         }
530 
531         /// <summary>
532 
533         /// 关闭所有的客户端会话,与所有的客户端连接会断开
534 
535         /// </summary>
536 
537         public void CloseAllClient()
538 
539         {
540 
541             foreach (SocketUDPState client in _clients)
542 
543             {
544 
545                 Close(client);
546 
547             }
548 
549             _clientCount = 0;
550 
551             _clients.Clear();
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 (_serverSock != null)
612 
613                         {
614 
615                             _serverSock = 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.Sock.Synchronous
16 
17 {
18 
19     public class SocketUDPState
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 }

 

服务器事件参数类:

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