文章系列目录
C#网络编程系列文章(一)之Socket实现异步TCP服务器
C#网络编程系列文章(二)之Socket实现同步TCP服务器
C#网络编程系列文章(三)之TcpListener实现异步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 namespace NetFrame.Net.TCP.Listener.Asynchronous 14 15 { 16 17 /// <summary> 18 19 /// TcpListener实现异步TCP服务器 20 21 /// </summary> 22 23 public class AsyncTCPServer : IDisposable 24 25 { 26 27 #region Fields 28 29 /// <summary> 30 31 /// 服务器程序允许的最大客户端连接数 32 33 /// </summary> 34 35 private int _maxClient; 36 37 38 39 /// <summary> 40 41 /// 当前的连接的客户端数 42 43 /// </summary> 44 45 private int _clientCount; 46 47 48 49 /// <summary> 50 51 /// 服务器使用的异步TcpListener 52 53 /// </summary> 54 55 private TcpListener _listener; 56 57 58 59 /// <summary> 60 61 /// 客户端会话列表 62 63 /// </summary> 64 65 private List<Object> _clients; 66 67 68 69 private bool disposed = false; 70 71 72 73 #endregion 74 75 76 77 #region Properties 78 79 80 81 /// <summary> 82 83 /// 服务器是否正在运行 84 85 /// </summary> 86 87 public bool IsRunning { get; private set; } 88 89 /// <summary> 90 91 /// 监听的IP地址 92 93 /// </summary> 94 95 public IPAddress Address { get; private set; } 96 97 /// <summary> 98 99 /// 监听的端口 100 101 /// </summary> 102 103 public int Port { get; private set; } 104 105 /// <summary> 106 107 /// 通信使用的编码 108 109 /// </summary> 110 111 public Encoding Encoding { get; set; } 112 113 114 115 116 117 #endregion 118 119 120 121 #region 构造函数 122 123 124 125 /// <summary> 126 127 /// 异步TCP服务器 128 129 /// </summary> 130 131 /// <param name="listenPort">监听的端口</param> 132 133 public AsyncTCPServer(int listenPort) 134 135 : this(IPAddress.Any, listenPort) 136 137 { 138 139 } 140 141 142 143 /// <summary> 144 145 /// 异步TCP服务器 146 147 /// </summary> 148 149 /// <param name="localEP">监听的终结点</param> 150 151 public AsyncTCPServer(IPEndPoint localEP) 152 153 : this(localEP.Address, localEP.Port) 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 public AsyncTCPServer(IPAddress localIPAddress, int listenPort) 172 173 { 174 175 Address = localIPAddress; 176 177 Port = listenPort; 178 179 this.Encoding = Encoding.Default; 180 181 182 183 _clients = new List<Object>(); 184 185 186 187 _listener = new TcpListener(Address, Port); 188 189 _listener.AllowNatTraversal(true); 190 191 } 192 193 194 195 #endregion 196 197 198 199 #region Method 200 201 202 203 /// <summary> 204 205 /// 启动服务器 206 207 /// </summary> 208 209 public void Start() 210 211 { 212 213 if (!IsRunning) 214 215 { 216 217 IsRunning = true; 218 219 _listener.Start(); 220 221 _listener.BeginAcceptTcpClient( 222 223 new AsyncCallback(HandleTcpClientAccepted), _listener); 224 225 } 226 227 } 228 229 230 231 232 233 /// <summary> 234 235 /// 启动服务器 236 237 /// </summary> 238 239 /// <param name="backlog"> 240 241 /// 服务器所允许的挂起连接序列的最大长度 242 243 /// </param> 244 245 public void Start(int backlog) 246 247 { 248 249 if (!IsRunning) 250 251 { 252 253 IsRunning = true; 254 255 _listener.Start(backlog); 256 257 _listener.BeginAcceptTcpClient( 258 259 new AsyncCallback(HandleTcpClientAccepted), _listener); 260 261 } 262 263 } 264 265 266 267 /// <summary> 268 269 /// 停止服务器 270 271 /// </summary> 272 273 public void Stop() 274 275 { 276 277 if (IsRunning) 278 279 { 280 281 IsRunning = false; 282 283 _listener.Stop(); 284 285 lock (_clients) 286 287 { 288 289 //关闭所有客户端连接 290 291 CloseAllClient(); 292 293 } 294 295 } 296 297 } 298 299 300 301 /// <summary> 302 303 /// 处理客户端连接的函数 304 305 /// </summary> 306 307 /// <param name="ar"></param> 308 309 private void HandleTcpClientAccepted(IAsyncResult ar) 310 311 { 312 313 if (IsRunning) 314 315 { 316 317 //TcpListener tcpListener = (TcpListener)ar.AsyncState; 318 319 320 321 TcpClient client = _listener.EndAcceptTcpClient(ar); 322 323 byte[] buffer = new byte[client.ReceiveBufferSize]; 324 325 326 327 TCPClientState state 328 329 = new TCPClientState(client, buffer); 330 331 lock (_clients) 332 333 { 334 335 _clients.Add(state); 336 337 RaiseClientConnected(state); 338 339 } 340 341 342 343 NetworkStream stream = state.NetworkStream; 344 345 //开始异步读取数据 346 347 stream.BeginRead(state.Buffer, 0, state.Buffer.Length, HandleDataReceived, state); 348 349 350 351 _listener.BeginAcceptTcpClient( 352 353 new AsyncCallback(HandleTcpClientAccepted), ar.AsyncState); 354 355 } 356 357 } 358 359 /// <summary> 360 361 /// 数据接受回调函数 362 363 /// </summary> 364 365 /// <param name="ar"></param> 366 367 private void HandleDataReceived(IAsyncResult ar) 368 369 { 370 371 if (IsRunning) 372 373 { 374 375 TCPClientState state = (TCPClientState)ar.AsyncState; 376 377 NetworkStream stream = state.NetworkStream; 378 379 380 381 int recv = 0; 382 383 try 384 385 { 386 387 recv = stream.EndRead(ar); 388 389 } 390 391 catch 392 393 { 394 395 recv = 0; 396 397 } 398 399 400 401 if (recv == 0) 402 403 { 404 405 // connection has been closed 406 407 lock (_clients) 408 409 { 410 411 _clients.Remove(state); 412 413 //触发客户端连接断开事件 414 415 RaiseClientDisconnected(state); 416 417 return; 418 419 } 420 421 } 422 423 424 425 // received byte and trigger event notification 426 427 byte[] buff = new byte[recv]; 428 429 Buffer.BlockCopy(state.Buffer, 0, buff, 0, recv); 430 431 //触发数据收到事件 432 433 RaiseDataReceived(state); 434 435 436 437 // continue listening for tcp datagram packets 438 439 stream.BeginRead(state.Buffer, 0, state.Buffer.Length, HandleDataReceived, state); 440 441 } 442 443 } 444 445 446 447 /// <summary> 448 449 /// 发送数据 450 451 /// </summary> 452 453 /// <param name="state">接收数据的客户端会话</param> 454 455 /// <param name="data">数据报文</param> 456 457 public void Send(TCPClientState state, byte[] data) 458 459 { 460 461 RaisePrepareSend(state); 462 463 Send(state.TcpClient, data); 464 465 } 466 467 468 469 /// <summary> 470 471 /// 异步发送数据至指定的客户端 472 473 /// </summary> 474 475 /// <param name="client">客户端</param> 476 477 /// <param name="data">报文</param> 478 479 public void Send(TcpClient client, byte[] data) 480 481 { 482 483 if (!IsRunning) 484 485 throw new InvalidProgramException("This TCP Scoket server has not been started."); 486 487 488 489 if (client == null) 490 491 throw new ArgumentNullException("client"); 492 493 494 495 if (data == null) 496 497 throw new ArgumentNullException("data"); 498 499 client.GetStream().BeginWrite(data, 0, data.Length, SendDataEnd, client); 500 501 } 502 503 504 505 /// <summary> 506 507 /// 发送数据完成处理函数 508 509 /// </summary> 510 511 /// <param name="ar">目标客户端Socket</param> 512 513 private void SendDataEnd(IAsyncResult ar) 514 515 { 516 517 ((TcpClient)ar.AsyncState).GetStream().EndWrite(ar); 518 519 RaiseCompletedSend(null); 520 521 } 522 523 #endregion 524 525 526 527 #region 事件 528 529 530 531 /// <summary> 532 533 /// 与客户端的连接已建立事件 534 535 /// </summary> 536 537 public event EventHandler<AsyncEventArgs> ClientConnected; 538 539 /// <summary> 540 541 /// 与客户端的连接已断开事件 542 543 /// </summary> 544 545 public event EventHandler<AsyncEventArgs> ClientDisconnected; 546 547 548 549 550 551 /// <summary> 552 553 /// 触发客户端连接事件 554 555 /// </summary> 556 557 /// <param name="state"></param> 558 559 private void RaiseClientConnected(TCPClientState state) 560 561 { 562 563 if (ClientConnected != null) 564 565 { 566 567 ClientConnected(this, new AsyncEventArgs(state)); 568 569 } 570 571 } 572 573 /// <summary> 574 575 /// 触发客户端连接断开事件 576 577 /// </summary> 578 579 /// <param name="client"></param> 580 581 private void RaiseClientDisconnected(TCPClientState state) 582 583 { 584 585 if (ClientDisconnected != null) 586 587 { 588 589 ClientDisconnected(this, new AsyncEventArgs("连接断开")); 590 591 } 592 593 } 594 595 596 597 /// <summary> 598 599 /// 接收到数据事件 600 601 /// </summary> 602 603 public event EventHandler<AsyncEventArgs> DataReceived; 604 605 606 607 private void RaiseDataReceived(TCPClientState state) 608 609 { 610 611 if (DataReceived != null) 612 613 { 614 615 DataReceived(this, new AsyncEventArgs(state)); 616 617 } 618 619 } 620 621 622 623 /// <summary> 624 625 /// 发送数据前的事件 626 627 /// </summary> 628 629 public event EventHandler<AsyncEventArgs> PrepareSend; 630 631 632 633 /// <summary> 634 635 /// 触发发送数据前的事件 636 637 /// </summary> 638 639 /// <param name="state"></param> 640 641 private void RaisePrepareSend(TCPClientState state) 642 643 { 644 645 if (PrepareSend != null) 646 647 { 648 649 PrepareSend(this, new AsyncEventArgs(state)); 650 651 } 652 653 } 654 655 656 657 /// <summary> 658 659 /// 数据发送完毕事件 660 661 /// </summary> 662 663 public event EventHandler<AsyncEventArgs> CompletedSend; 664 665 666 667 /// <summary> 668 669 /// 触发数据发送完毕的事件 670 671 /// </summary> 672 673 /// <param name="state"></param> 674 675 private void RaiseCompletedSend(TCPClientState state) 676 677 { 678 679 if (CompletedSend != null) 680 681 { 682 683 CompletedSend(this, new AsyncEventArgs(state)); 684 685 } 686 687 } 688 689 690 691 /// <summary> 692 693 /// 网络错误事件 694 695 /// </summary> 696 697 public event EventHandler<AsyncEventArgs> NetError; 698 699 /// <summary> 700 701 /// 触发网络错误事件 702 703 /// </summary> 704 705 /// <param name="state"></param> 706 707 private void RaiseNetError(TCPClientState state) 708 709 { 710 711 if (NetError != null) 712 713 { 714 715 NetError(this, new AsyncEventArgs(state)); 716 717 } 718 719 } 720 721 722 723 /// <summary> 724 725 /// 异常事件 726 727 /// </summary> 728 729 public event EventHandler<AsyncEventArgs> OtherException; 730 731 /// <summary> 732 733 /// 触发异常事件 734 735 /// </summary> 736 737 /// <param name="state"></param> 738 739 private void RaiseOtherException(TCPClientState state, string descrip) 740 741 { 742 743 if (OtherException != null) 744 745 { 746 747 OtherException(this, new AsyncEventArgs(descrip, state)); 748 749 } 750 751 } 752 753 private void RaiseOtherException(TCPClientState state) 754 755 { 756 757 RaiseOtherException(state, ""); 758 759 } 760 761 762 763 #endregion 764 765 766 767 #region Close 768 769 /// <summary> 770 771 /// 关闭一个与客户端之间的会话 772 773 /// </summary> 774 775 /// <param name="state">需要关闭的客户端会话对象</param> 776 777 public void Close(TCPClientState state) 778 779 { 780 781 if (state != null) 782 783 { 784 785 state.Close(); 786 787 _clients.Remove(state); 788 789 _clientCount--; 790 791 //TODO 触发关闭事件 792 793 } 794 795 } 796 797 /// <summary> 798 799 /// 关闭所有的客户端会话,与所有的客户端连接会断开 800 801 /// </summary> 802 803 public void CloseAllClient() 804 805 { 806 807 foreach (TCPClientState client in _clients) 808 809 { 810 811 Close(client); 812 813 } 814 815 _clientCount = 0; 816 817 _clients.Clear(); 818 819 } 820 821 #endregion 822 823 824 825 #region 释放 826 827 /// <summary> 828 829 /// Performs application-defined tasks associated with freeing, 830 831 /// releasing, or resetting unmanaged resources. 832 833 /// </summary> 834 835 public void Dispose() 836 837 { 838 839 Dispose(true); 840 841 GC.SuppressFinalize(this); 842 843 } 844 845 846 847 /// <summary> 848 849 /// Releases unmanaged and - optionally - managed resources 850 851 /// </summary> 852 853 /// <param name="disposing"><c>true</c> to release 854 855 /// both managed and unmanaged resources; <c>false</c> 856 857 /// to release only unmanaged resources.</param> 858 859 protected virtual void Dispose(bool disposing) 860 861 { 862 863 if (!this.disposed) 864 865 { 866 867 if (disposing) 868 869 { 870 871 try 872 873 { 874 875 Stop(); 876 877 if (_listener != null) 878 879 { 880 881 _listener = null; 882 883 } 884 885 } 886 887 catch (SocketException) 888 889 { 890 891 //TODO 892 893 RaiseOtherException(null); 894 895 } 896 897 } 898 899 disposed = true; 900 901 } 902 903 } 904 905 #endregion 906 907 } 908 909 }
客户端处理封装类:
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 12 13 namespace NetFrame.Net.TCP.Listener.Asynchronous 14 15 { 16 17 public class TCPClientState 18 19 { 20 21 /// <summary> 22 23 /// 与客户端相关的TcpClient 24 25 /// </summary> 26 27 public TcpClient TcpClient { get; private set; } 28 29 30 31 /// <summary> 32 33 /// 获取缓冲区 34 35 /// </summary> 36 37 public byte[] Buffer { get; private set; } 38 39 40 41 /// <summary> 42 43 /// 获取网络流 44 45 /// </summary> 46 47 public NetworkStream NetworkStream 48 49 { 50 51 get { return TcpClient.GetStream(); } 52 53 } 54 55 56 57 public TCPClientState(TcpClient tcpClient, byte[] buffer) 58 59 { 60 61 if (tcpClient == null) 62 63 throw new ArgumentNullException("tcpClient"); 64 65 if (buffer == null) 66 67 throw new ArgumentNullException("buffer"); 68 69 70 71 this.TcpClient = tcpClient; 72 73 this.Buffer = buffer; 74 75 } 76 77 /// <summary> 78 79 /// 关闭 80 81 /// </summary> 82 83 public void Close() 84 85 { 86 87 //关闭数据的接受和发送 88 89 TcpClient.Close(); 90 91 Buffer = null; 92 93 } 94 95 } 96 97 }
服务器事件参数类:
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.Asynchronous 12 13 { 14 15 /// <summary> 16 17 /// 异步TcpListener TCP服务器事件参数类 18 19 /// </summary> 20 21 public class AsyncEventArgs: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 TCPClientState _state; 42 43 44 45 /// <summary> 46 47 /// 是否已经处理过了 48 49 /// </summary> 50 51 public bool IsHandled { get; set; } 52 53 54 55 public AsyncEventArgs(string msg) 56 57 { 58 59 this._msg = msg; 60 61 IsHandled = false; 62 63 } 64 65 public AsyncEventArgs(TCPClientState state) 66 67 { 68 69 this._state = state; 70 71 IsHandled = false; 72 73 } 74 75 public AsyncEventArgs(string msg, TCPClientState state) 76 77 { 78 79 this._msg = msg; 80 81 this._state = state; 82 83 IsHandled = false; 84 85 } 86 87 } 88 89 }

浙公网安备 33010602011771号