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

浙公网安备 33010602011771号