Пример #1
0
        private void CloseClientSocket(SocketAsyncEventArgs e, string reason)
        {
            AsyncUserToken aut = e.UserToken as AsyncUserToken;
            TMSKSocket     s   = null;

            try
            {
                s = aut.CurrentSocket;
                string ip = "未知";
                try
                {
                    ip = string.Format("{0}", s.RemoteEndPoint);
                }
                catch (Exception)
                {
                }
                LogManager.WriteLog(LogTypes.Error, string.Format("远程连接关闭: {0}, 当前总共: {1}, 原因1:{2}, 原因2:{3}", new object[]
                {
                    ip,
                    this.ConnectedSocketsCount,
                    reason,
                    s.CloseReason
                }), null, true);
                this.CloseSocket(s, "");
            }
            finally
            {
                aut.CurrentSocket = null;
                aut.Tag           = null;
                if (e.LastOperation == SocketAsyncOperation.Send)
                {
                    e.SetBuffer(null, 0, 0);
                    if (null != s)
                    {
                        s.PushWriteSocketAsyncEventArgs(e);
                    }
                }
                else if (e.LastOperation == SocketAsyncOperation.Receive)
                {
                    if (null != s)
                    {
                        s.PushReadSocketAsyncEventArgs(e);
                    }
                }
            }
        }
Пример #2
0
        public bool SendData(TMSKSocket s, byte[] buffer, int offset, int count, MemoryBlock item, SendBuffer sendBuffer)
        {
            this.GTotalSendCount++;
            SocketAsyncEventArgs writeEventArgs = s.PopWriteSocketAsyncEventArgs();

            if (null == writeEventArgs)
            {
                writeEventArgs            = new SocketAsyncEventArgs();
                writeEventArgs.Completed += this.OnIOCompleted;
                writeEventArgs.UserToken  = new AsyncUserToken
                {
                    CurrentSocket = null,
                    Tag           = null
                };
            }
            writeEventArgs.SetBuffer(buffer, offset, count);
            AsyncUserToken userToken = writeEventArgs.UserToken as AsyncUserToken;

            userToken.CurrentSocket = s;
            userToken.Tag           = item;
            userToken._SendBuffer   = sendBuffer;
            bool exception = false;

            if (!this._SendAsync(writeEventArgs, out exception))
            {
                this.ProcessSend(writeEventArgs);
            }
            if (exception)
            {
                if (null != this.SocketSended)
                {
                    this.SocketSended(this, writeEventArgs);
                }
                writeEventArgs.SetBuffer(null, 0, 0);
                userToken.CurrentSocket = null;
                userToken.Tag           = null;
                s.PushWriteSocketAsyncEventArgs(writeEventArgs);
            }
            return(!exception);
        }
Пример #3
0
        /// <summary>
        /// Close the socket associated with the client.
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed send/receive operation.</param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken aut = e.UserToken as AsyncUserToken;

            try
            {
                Socket s = aut.CurrentSocket;
                if (!FindSocket(s)) //已经关闭了
                {
                    return;
                }

                RemoveSocket(s);

                try
                {
                    LogManager.WriteLog(LogTypes.Info, string.Format("关闭客户端连接: {0}, 操作: {1}, 原因: {2}", s.RemoteEndPoint, e.LastOperation, e.SocketError));
                }
                catch (Exception)
                {
                }

                // Decrement the counter keeping track of the total number of clients connected to the server.
                this.semaphoreAcceptedClients.Release(); //有时会超过最大数
                Interlocked.Decrement(ref this.numConnectedSockets);

                /// 断开成功通知函数
                if (null != SocketClosed)
                {
                    SocketClosed(this, e);
                }

                try
                {
                    s.Shutdown(SocketShutdown.Both);
                }
                catch (Exception)
                {
                    // Throws if client process has already closed.
                }

                try
                {
                    s.Close();
                }
                catch (Exception)
                {
                }
            }
            finally
            {
                aut.CurrentSocket = null; //释放
                aut.Tag           = null; //释放

                // Free the SocketAsyncEventArg so they can be reused by another client.
                if (e.LastOperation == SocketAsyncOperation.Send)
                {
                    e.SetBuffer(null, 0, 0); //回收内存
                    this.writePool.Push(e);
                }
                else if (e.LastOperation == SocketAsyncOperation.Receive)
                {
                    this.readPool.Push(e);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// 向客户端发送数据
        /// </summary>
        /// <param name="data"></param>
        public bool SendData(TMSKSocket s, Byte[] buffer, int offset, int count, MemoryBlock item, SendBuffer sendBuffer)
        {
            GTotalSendCount++;
            SocketAsyncEventArgs writeEventArgs;

            if (GameManager.FlagOptimizeThreadPool3)
            {
                writeEventArgs = s.PopWriteSocketAsyncEventArgs(); //线程安全的操作
            }
            else
            {
                writeEventArgs = this.writePool.Pop(); //线程安全的操作
            }
            if (null == writeEventArgs)
            {
                writeEventArgs            = new SocketAsyncEventArgs();
                writeEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnIOCompleted);
                writeEventArgs.UserToken  = new AsyncUserToken()
                {
                    CurrentSocket = null, Tag = null
                };
            }

            writeEventArgs.SetBuffer(buffer, offset, count);
            AsyncUserToken userToken = (writeEventArgs.UserToken as AsyncUserToken);

            userToken.CurrentSocket = s;
            userToken.Tag           = item;
            userToken._SendBuffer   = sendBuffer;

            bool exception = false;

            if (GameManager.FlagSkipSocketSend && GameManager.CanSkipCmd(s))
            {
                writeEventArgs.SocketError = SocketError.Success;
                this.ProcessSend(writeEventArgs);
            }
            else
            {
                Boolean willRaiseEvent = _SendAsync(writeEventArgs, out exception);
                if (!willRaiseEvent)
                {
                    this.ProcessSend(writeEventArgs);
                }
            }

            if (exception) //此处不处理会导致内存泄露
            {
                /// 发送数据通知函数
                if (null != SocketSended)
                {
                    SocketSended(this, writeEventArgs);
                }

                //什么事情都不做, 收回使用的e和buffer
                // Free the SocketAsyncEventArg so they can be reused by another client.
                writeEventArgs.SetBuffer(null, 0, 0); //回收内存
                userToken.CurrentSocket = null;       //释放
                userToken.Tag           = null;       //释放
                if (GameManager.FlagOptimizeThreadPool3)
                {
                    s.PushWriteSocketAsyncEventArgs(writeEventArgs);
                }
                else
                {
                    this.writePool.Push(writeEventArgs);
                }
            }

            return(!exception);
        }
Пример #5
0
        /// <summary>
        /// Close the socket associated with the client.
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed send/receive operation.</param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken aut = e.UserToken as AsyncUserToken;

            TMSKSocket s = null;

            try
            {
                s = aut.CurrentSocket;

                string ip = "未知";

                try
                {
                    ip = string.Format("{0}", s.RemoteEndPoint);
                }
                catch (System.Exception)
                {
                }

                LogManager.WriteLog(LogTypes.Error, string.Format("远程连接关闭: {0}, 当前总共: {1}", ip, ConnectedSocketsCount));

                CloseSocket(s);
            }
            finally
            {
                aut.CurrentSocket = null; //释放
                aut.Tag           = null; //释放

                // Free the SocketAsyncEventArg so they can be reused by another client.
                if (e.LastOperation == SocketAsyncOperation.Send)
                {
                    e.SetBuffer(null, 0, 0); //回收内存
                    if (GameManager.FlagOptimizeThreadPool3)
                    {
                        //TMSKThreadStaticClass.GetInstance().PushReadSocketAsyncEventArgs(e);
                        if (null != s)
                        {
                            s.PushWriteSocketAsyncEventArgs(e);
                        }
                    }
                    else
                    {
                        this.writePool.Push(e);
                    }
                }
                else if (e.LastOperation == SocketAsyncOperation.Receive)
                {
                    if (GameManager.FlagOptimizeThreadPool3)
                    {
                        //TMSKThreadStaticClass.GetInstance().PushReadSocketAsyncEventArgs(e);
                        if (null != s)
                        {
                            s.PushReadSocketAsyncEventArgs(e);
                        }
                    }
                    else
                    {
                        this.readPool.Push(e);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// This method is invoked when an asynchronous receive operation completes.
        /// If the remote host closed the connection, then the socket is closed.
        /// If data was received then the data is echoed back to the client.
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed receive operation.</param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            AsyncUserToken userToken = (e.UserToken as AsyncUserToken);
            TMSKSocket     s         = userToken.CurrentSocket;

            // Check if the remote host closed the connection.
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                // Increment the count of the total bytes receive by the server.
                Interlocked.Add(ref this.totalBytesRead, e.BytesTransferred);

                bool recvReturn = true;

                // Get the message received from the listener.
                //e.Buffer, e.Offset, e.bytesTransferred);
                //通知外部有新的socket到达
                if (null != SocketReceived)
                {
                    //字节排序
                    if (GameManager.FlagUseWin32Decrypt)
                    {
                        //使用动态库解密
                        int length = e.BytesTransferred;
                        unsafe
                        {
                            fixed(byte *p = e.Buffer)
                            {
                                Win32API.SortBytes(p, e.Offset, e.BytesTransferred, s.SortKey64);
                            }
                        }
                    }
                    else
                    {
                        // Win32API.SortBytes(e.Buffer, e.Offset, e.BytesTransferred, s.SortKey64);
                        DataHelper.SortBytes(e.Buffer, e.Offset, e.BytesTransferred, s.SortKey64);
                    }

                    try
                    {
                        recvReturn = SocketReceived(this, e);
                    }
                    catch (System.Exception ex)
                    {
                        SysConOut.WriteLine("接收数据异常" + ex.ToString());
                        //所有异常应当在下层捕获,不应抛到这层来
                        LogManager.WriteException(ex.ToString());
                        recvReturn = false;
                    }
                }

                if (recvReturn)
                {
                    //继续接收流程(以数据流为驱动)
                    Boolean willRaiseEvent = _ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    SysConOut.WriteLine("接收数据recvReturn = false");
                    UInt16 lastPacketCmd = TCPManager.getInstance().LastPacketCmdID(s);
                    string reason        = string.Format("CMD={0}", ((TCPGameServerCmds)lastPacketCmd).ToString());
                    this.CloseClientSocket(e, reason);
                }
            }
            else
            {
                SysConOut.WriteLine(string.Format("接收数据{0}--{1}", e.BytesTransferred, e.SocketError.ToString()));
                string reason = string.Format("[{0}]{1}", (int)e.SocketError, e.SocketError.ToString());
                this.CloseClientSocket(e, reason);
            }
        }