TcpAsyncSocketListener.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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.SocketBase;
  8. using SuperSocket.SocketBase.Config;
  9. using SuperSocket.SocketBase.Logging;
  10. namespace SuperSocket.SocketEngine
  11. {
  12. /// <summary>
  13. /// Tcp socket listener in async mode
  14. /// </summary>
  15. class TcpAsyncSocketListener : SocketListenerBase
  16. {
  17. private int m_ListenBackLog;
  18. private Socket m_ListenSocket;
  19. private SocketAsyncEventArgs m_AcceptSAE;
  20. public TcpAsyncSocketListener(ListenerInfo info)
  21. : base(info)
  22. {
  23. m_ListenBackLog = info.BackLog;
  24. }
  25. /// <summary>
  26. /// Starts to listen
  27. /// </summary>
  28. /// <param name="config">The server config.</param>
  29. /// <returns></returns>
  30. public override bool Start(IServerConfig config)
  31. {
  32. m_ListenSocket = new Socket(this.Info.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  33. try
  34. {
  35. m_ListenSocket.Bind(this.Info.EndPoint);
  36. m_ListenSocket.Listen(m_ListenBackLog);
  37. m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
  38. m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
  39. SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs();
  40. m_AcceptSAE = acceptEventArg;
  41. acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(acceptEventArg_Completed);
  42. if (!m_ListenSocket.AcceptAsync(acceptEventArg))
  43. ProcessAccept(acceptEventArg);
  44. return true;
  45. }
  46. catch (Exception e)
  47. {
  48. OnError(e);
  49. return false;
  50. }
  51. }
  52. void acceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
  53. {
  54. ProcessAccept(e);
  55. }
  56. void ProcessAccept(SocketAsyncEventArgs e)
  57. {
  58. Socket socket = null;
  59. if (e.SocketError != SocketError.Success)
  60. {
  61. var errorCode = (int)e.SocketError;
  62. //The listen socket was closed
  63. if (errorCode == 995 || errorCode == 10004 || errorCode == 10038)
  64. return;
  65. OnError(new SocketException(errorCode));
  66. }
  67. else
  68. {
  69. socket = e.AcceptSocket;
  70. }
  71. e.AcceptSocket = null;
  72. bool willRaiseEvent = false;
  73. try
  74. {
  75. willRaiseEvent = m_ListenSocket.AcceptAsync(e);
  76. }
  77. catch (ObjectDisposedException)
  78. {
  79. //The listener was stopped
  80. //Do nothing
  81. //make sure ProcessAccept won't be executed in this thread
  82. willRaiseEvent = true;
  83. }
  84. catch (NullReferenceException)
  85. {
  86. //The listener was stopped
  87. //Do nothing
  88. //make sure ProcessAccept won't be executed in this thread
  89. willRaiseEvent = true;
  90. }
  91. catch (Exception exc)
  92. {
  93. OnError(exc);
  94. //make sure ProcessAccept won't be executed in this thread
  95. willRaiseEvent = true;
  96. }
  97. if (socket != null)
  98. OnNewClientAccepted(socket, null);
  99. if (!willRaiseEvent)
  100. ProcessAccept(e);
  101. }
  102. public override void Stop()
  103. {
  104. if (m_ListenSocket == null)
  105. return;
  106. lock (this)
  107. {
  108. if (m_ListenSocket == null)
  109. return;
  110. m_AcceptSAE.Completed -= new EventHandler<SocketAsyncEventArgs>(acceptEventArg_Completed);
  111. m_AcceptSAE.Dispose();
  112. m_AcceptSAE = null;
  113. try
  114. {
  115. m_ListenSocket.Close();
  116. }
  117. finally
  118. {
  119. m_ListenSocket = null;
  120. }
  121. }
  122. OnStopped();
  123. }
  124. }
  125. }