void eventArgs_Completed(object sender, SocketAsyncEventArgs e) { e.Completed -= new EventHandler <SocketAsyncEventArgs>(eventArgs_Completed); if (e.SocketError != SocketError.Success) { var errorCode = (int)e.SocketError; //The listen socket was closed if (errorCode == 995 || errorCode == 10004 || errorCode == 10038) { return; } OnError(new SocketException(errorCode)); } if (e.LastOperation == SocketAsyncOperation.ReceiveFrom) { try { OnNewClientAccepted(m_ListenSocket, e); } catch (Exception exc) { OnError(exc); m_SaePool.Return(e.UserToken as SaeState); } SaeState newState = null; try { newState = m_SaePool.Get(); var sae = newState.Sae; sae.UserToken = newState; sae.RemoteEndPoint = m_AnyEndPoint; sae.Completed += new EventHandler <SocketAsyncEventArgs>(eventArgs_Completed); if (!m_ListenSocket.ReceiveFromAsync(sae)) { eventArgs_Completed(this, sae); } } catch (Exception exc) { OnError(exc); if (newState != null) { newState.Sae.Completed -= new EventHandler <SocketAsyncEventArgs>(eventArgs_Completed); m_SaePool.Return(newState); } } } }
/// <summary> /// Starts to listen /// </summary> /// <param name="config">The server config.</param> /// <returns></returns> public override bool Start(IServerConfig config) { SaeState saeState = null; try { m_ListenSocket = new Socket(this.EndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); m_ListenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); m_ListenSocket.Bind(this.EndPoint); //Mono doesn't support it if (Platform.SupportSocketIOControlByCodeEnum) { uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; byte[] optionInValue = { Convert.ToByte(false) }; byte[] optionOutValue = new byte[4]; m_ListenSocket.IOControl((int)SIO_UDP_CONNRESET, optionInValue, optionOutValue); } saeState = m_SaePool.Get(); var sae = saeState.Sae; sae.UserToken = saeState; sae.RemoteEndPoint = m_AnyEndPoint; sae.Completed += new EventHandler <SocketAsyncEventArgs>(eventArgs_Completed); if (!m_ListenSocket.ReceiveFromAsync(sae)) { eventArgs_Completed(this, sae); } return(true); } catch (Exception e) { if (saeState != null) { saeState.Sae.Completed -= new EventHandler <SocketAsyncEventArgs>(eventArgs_Completed); m_SaePool.Return(saeState); } OnError(e); return(false); } }
void ProcessPackageWithSessionID(Socket listenSocket, IPEndPoint remoteEndPoint, ArraySegment <byte> receivedData, SaeState saeState) { TPackageInfo requestInfo; string sessionID; int rest; try { var receiveData = new BufferList(); receiveData.Add(receivedData, saeState); requestInfo = this.m_UdpRequestFilter.Filter(receiveData, out rest); } catch (Exception exc) { if (AppServer.Logger.IsErrorEnabled) { AppServer.Logger.Error("Failed to parse UDP package!", exc); } return; } var udpRequestInfo = requestInfo as IUdpPackageInfo; if (rest > 0) { if (AppServer.Logger.IsErrorEnabled) { AppServer.Logger.Error("The output parameter rest must be zero in this case!"); } return; } if (udpRequestInfo == null) { if (AppServer.Logger.IsErrorEnabled) { AppServer.Logger.Error("Invalid UDP package format!"); } return; } if (string.IsNullOrEmpty(udpRequestInfo.SessionID)) { if (AppServer.Logger.IsErrorEnabled) { AppServer.Logger.Error("Failed to get session key from UDP package!"); } return; } sessionID = udpRequestInfo.SessionID; var appSession = AppServer.GetSessionByID(sessionID); if (appSession == null) { if (!DetectConnectionNumber(remoteEndPoint)) { return; } var socketSession = new UdpSocketSession(listenSocket, remoteEndPoint, sessionID); appSession = AppServer.CreateAppSession(socketSession); if (appSession == null) { return; } if (!DetectConnectionNumber(remoteEndPoint)) { return; } if (!AppServer.RegisterSession(appSession)) { return; } Interlocked.Increment(ref m_ConnectionCount); socketSession.Closed += OnSocketSessionClosed; socketSession.Start(); } else { var socketSession = appSession.SocketSession as UdpSocketSession; //Client remote endpoint may change, so update session to ensure the server can find client correctly socketSession.UpdateRemoteEndPoint(remoteEndPoint); } m_RequestHandler.ExecuteCommand(appSession, requestInfo); }
void ProcessPackageWithoutSessionID(Socket listenSocket, IPEndPoint remoteEndPoint, ArraySegment <byte> receivedData, SaeState saeState) { var sessionID = remoteEndPoint.ToString(); var appSession = AppServer.GetSessionByID(sessionID); if (appSession == null) //New session { if (!DetectConnectionNumber(remoteEndPoint)) { return; } var socketSession = new UdpSocketSession(listenSocket, remoteEndPoint, sessionID); appSession = AppServer.CreateAppSession(socketSession); if (appSession == null) { return; } if (!DetectConnectionNumber(remoteEndPoint)) { return; } if (!AppServer.RegisterSession(appSession)) { return; } Interlocked.Increment(ref m_ConnectionCount); socketSession.Closed += OnSocketSessionClosed; socketSession.Start(); } ((UdpSocketSession)appSession.SocketSession).ProcessReceivedData(receivedData, saeState); }