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

浙公网安备 33010602011771号