文章系列目录
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 }

浙公网安备 33010602011771号