无网不进  
软硬件开发

文章系列目录

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

本文介绍
TcpListener 类提供一些简单方法,用于在阻止同步模式下侦听和接受传入连接请求。 可使用 TcpClient 或 Socket 来连接 TcpListener。 可使用 IPEndPoint、本地 IP 地址及端口号或者仅使用端口号,来创建 TcpListener。 可以将本地 IP 地址指定为 Any,将本地端口号指定为 0(如果希望基础服务提供程序为您分配这些值)。 如果您选择这样做,可在连接套接字后使用 LocalEndpoint 属性来标识已指定的信息。使用 Start 方法,可开始侦听传入的连接请求。
 Start 将对传入连接进行排队,直至您调用 Stop 方法或它已经完成 MaxConnections 排队为止。 可使用 AcceptSocket 或 AcceptTcpClient 从传入连接请求队列提取连接。 这两种方法将阻止。 如果要避免阻止,可首先使用 Pending 方法来确定队列中是否有可用的连接请求。
虽然TcpListener已经封装的比较不错了,我们于是就使用它在构造一个比较不错的同步TCP服务器,这里依然和前两章一样,给出服务器中的代码,代码中注释很详细,我也会给出相关的封装类。
TcpListener同步TCP服务器:

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

客户端处理封装类:

  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.IO;
 12 
 13  
 14 
 15 namespace NetFrame.Net.TCP.Listener.Synchronous
 16 
 17 {
 18 
 19     /// <summary>
 20 
 21     /// TcpListener实现同步TCP服务器 的客户端连接处理类
 22 
 23     /// </summary>
 24 
 25     public class TCPClientHandle
 26 
 27     {
 28 
 29         private TcpClient _tcpclient;
 30 
 31  
 32 
 33         private BinaryReader rs;
 34 
 35  
 36 
 37         private BinaryWriter ws;
 38 
 39  
 40 
 41         /// <summary>
 42 
 43         /// 标识是否与客户端相连接
 44 
 45         /// </summary>
 46 
 47         private bool _is_connect;
 48 
 49         public bool IsConnect
 50 
 51         {
 52 
 53             get { return _is_connect; }
 54 
 55             set { _is_connect = value; }
 56 
 57         }
 58 
 59  
 60 
 61         /// <summary>
 62 
 63         /// 数据接受缓冲区
 64 
 65         /// </summary>
 66 
 67         private byte[] _recvBuffer;
 68 
 69  
 70 
 71         public TCPClientHandle(TcpClient client)
 72 
 73         {
 74 
 75             _tcpclient = client;
 76 
 77             rs = new BinaryReader(client.GetStream());
 78 
 79             ws = new BinaryWriter(client.GetStream());
 80 
 81             // NetworkStream ns = tmpTcpClient.GetStream();
 82 
 83             // if(ns.CanRead&&ns.CanWrite)
 84 
 85             _recvBuffer=new byte[client.ReceiveBufferSize];
 86 
 87         }
 88 
 89  
 90 
 91         /// <summary>
 92 
 93         /// 接受数据
 94 
 95         /// </summary>
 96 
 97         public void RecevieData()
 98 
 99         {
100 
101             int len = 0;
102 
103             while (_is_connect)
104 
105             {
106 
107                 try
108 
109                 {
110 
111                     len = rs.Read(_recvBuffer, 0, _recvBuffer.Length);
112 
113                 }
114 
115                 catch (Exception)
116 
117                 {
118 
119                     break;
120 
121                 }
122 
123                 if (len == 0)
124 
125                 {
126 
127                     //the client has disconnected from server
128 
129                     break;
130 
131                 }
132 
133                 //TODO 处理收到的数据
134 
135                 
136 
137             }
138 
139         }
140 
141         /// <summary>
142 
143         /// 向客户端发送数据
144 
145         /// </summary>
146 
147         /// <param name="msg"></param>
148 
149         public void SendData(string msg)
150 
151         {
152 
153             byte[] data = Encoding.Default.GetBytes(msg);
154 
155             try
156 
157             {
158 
159                 ws.Write(data, 0, data.Length);
160 
161                 ws.Flush();
162 
163             }
164 
165             catch (Exception)
166 
167             {
168 
169                 //TODO 处理异常
170 
171             }
172 
173         }
174 
175  
176 
177         #region 事件
178 
179  
180 
181  
182 
183         //TODO 消息发送事件
184 
185         //TODO 数据收到事件
186 
187         //TODO 异常处理事件
188 
189  
190 
191         #endregion
192 
193  
194 
195         #region 释放
196 
197         /// <summary>
198 
199         /// Performs application-defined tasks associated with freeing, 
200 
201         /// releasing, or resetting unmanaged resources.
202 
203         /// </summary>
204 
205         public void Dispose()
206 
207         {
208 
209             _is_connect = false;
210 
211             if (_tcpclient != null)
212 
213             {
214 
215                 _tcpclient.Close();
216 
217                 _tcpclient = null;
218 
219             }
220 
221             GC.SuppressFinalize(this);
222 
223         }
224 
225  
226 
227         #endregion
228 
229     }
230 
231 }

Tcp服务器事件参数类:

 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.TCP.Listener.Synchronous
12 
13 {
14 
15     /// <summary>
16 
17     /// 同步TcpListener TCP服务器事件类
18 
19     /// </summary>
20 
21     public class TCPEventArgs : 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 TCPClientHandle _handle;
42 
43  
44 
45         /// <summary>
46 
47         /// 是否已经处理过了
48 
49         /// </summary>
50 
51         public bool IsHandled { get; set; }
52 
53  
54 
55         public TCPEventArgs(string msg)
56 
57         {
58 
59             this._msg = msg;
60 
61             IsHandled = false;
62 
63         }
64 
65         public TCPEventArgs(TCPClientHandle handle)
66 
67         {
68 
69             this._handle = handle;
70 
71             IsHandled = false;
72 
73         }
74 
75         public TCPEventArgs(string msg, TCPClientHandle handle)
76 
77         {
78 
79             this._msg = msg;
80 
81             this._handle = handle;
82 
83             IsHandled = false;
84 
85         }
86 
87     }
88 
89 }

 

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