Beispiel #1
0
        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);
                    }
                }
            }
        }
Beispiel #2
0
        /// <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);
        }