UdpSocketListener.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using SuperSocket.Common;
  8. using SuperSocket.SocketBase;
  9. using SuperSocket.SocketBase.Config;
  10. namespace SuperSocket.SocketEngine
  11. {
  12. class UdpSocketListener : SocketListenerBase
  13. {
  14. private Socket m_ListenSocket;
  15. private SocketAsyncEventArgs m_ReceiveSAE;
  16. public UdpSocketListener(ListenerInfo info)
  17. : base(info)
  18. {
  19. }
  20. /// <summary>
  21. /// Starts to listen
  22. /// </summary>
  23. /// <param name="config">The server config.</param>
  24. /// <returns></returns>
  25. public override bool Start(IServerConfig config)
  26. {
  27. try
  28. {
  29. m_ListenSocket = new Socket(this.EndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
  30. m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  31. m_ListenSocket.Bind(this.EndPoint);
  32. //Mono doesn't support it
  33. if (Platform.SupportSocketIOControlByCodeEnum)
  34. {
  35. uint IOC_IN = 0x80000000;
  36. uint IOC_VENDOR = 0x18000000;
  37. uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
  38. byte[] optionInValue = { Convert.ToByte(false) };
  39. byte[] optionOutValue = new byte[4];
  40. m_ListenSocket.IOControl((int)SIO_UDP_CONNRESET, optionInValue, optionOutValue);
  41. }
  42. var eventArgs = new SocketAsyncEventArgs();
  43. m_ReceiveSAE = eventArgs;
  44. eventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(eventArgs_Completed);
  45. eventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
  46. int receiveBufferSize = config.ReceiveBufferSize <= 0 ? 2048 : config.ReceiveBufferSize;
  47. var buffer = new byte[receiveBufferSize];
  48. eventArgs.SetBuffer(buffer, 0, buffer.Length);
  49. m_ListenSocket.ReceiveFromAsync(eventArgs);
  50. return true;
  51. }
  52. catch (Exception e)
  53. {
  54. OnError(e);
  55. return false;
  56. }
  57. }
  58. void eventArgs_Completed(object sender, SocketAsyncEventArgs e)
  59. {
  60. if (e.SocketError != SocketError.Success)
  61. {
  62. var errorCode = (int)e.SocketError;
  63. //The listen socket was closed
  64. if (errorCode == 995 || errorCode == 10004 || errorCode == 10038)
  65. return;
  66. OnError(new SocketException(errorCode));
  67. }
  68. if (e.LastOperation == SocketAsyncOperation.ReceiveFrom)
  69. {
  70. try
  71. {
  72. OnNewClientAcceptedAsync(m_ListenSocket, new object[] { e.Buffer.CloneRange(e.Offset, e.BytesTransferred), e.RemoteEndPoint.Serialize() });
  73. }
  74. catch (Exception exc)
  75. {
  76. OnError(exc);
  77. }
  78. try
  79. {
  80. m_ListenSocket.ReceiveFromAsync(e);
  81. }
  82. catch (Exception exc)
  83. {
  84. OnError(exc);
  85. }
  86. }
  87. }
  88. public override void Stop()
  89. {
  90. if (m_ListenSocket == null)
  91. return;
  92. lock(this)
  93. {
  94. if (m_ListenSocket == null)
  95. return;
  96. m_ReceiveSAE.Completed -= new EventHandler<SocketAsyncEventArgs>(eventArgs_Completed);
  97. m_ReceiveSAE.Dispose();
  98. m_ReceiveSAE = null;
  99. if(!Platform.IsMono)
  100. {
  101. try
  102. {
  103. m_ListenSocket.Shutdown(SocketShutdown.Both);
  104. }
  105. catch { }
  106. }
  107. try
  108. {
  109. m_ListenSocket.Close();
  110. }
  111. catch { }
  112. finally
  113. {
  114. m_ListenSocket = null;
  115. }
  116. }
  117. OnStopped();
  118. }
  119. }
  120. }