예제 #1
0
        /// <summary>
        /// 当一个SocketAsyncEventArgs断开后,我们需要断开对应的Socket连接,并释放对应资源
        /// </summary>
        /// <param name="userToken"></param>
        public void CloseSocket(AsyncSocketUserToken userToken)
        {
            if (userToken.ConnectSocket == null)
            {
                return;
            }

            Interlocked.Decrement(ref ConnectionCount);
            string socketInfo = string.Format("Local Address: {0} Remote Address: {1}", userToken.ConnectSocket.LocalEndPoint,
                                              userToken.ConnectSocket.RemoteEndPoint);

            LogHelper.Info(string.Format("Client connection disconnected. {0}", socketInfo));


            if (this.ReceivedMinerConnectionAction != null)
            {
                this.ReceivedMinerConnectionAction(userToken, true);
            }

            try
            {
                userToken.ConnectSocket.Shutdown(SocketShutdown.Both);
            }
            catch (Exception E)
            {
                LogHelper.Error(string.Format("CloseClientSocket Disconnect client {0} error, message: {1}", socketInfo, E.Message));
            }
            userToken.ConnectSocket.Close();
            userToken.ConnectSocket = null; //释放引用,并清理缓存,包括释放协议对象等资源

            m_maxNumberAcceptedClients.Release();
            m_asyncSocketUserTokenPool.Push(userToken);
            m_asyncSocketUserTokenList.Remove(userToken);
        }
예제 #2
0
        /// <summary>
        /// NET底层IO线程也是每个异步事件都是由不同的线程返回到Completed事件,
        /// 因此在Completed事件需要对用户对象进行加锁,
        /// 避免同一个用户对象同时触发两个Completed事件。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="asyncEventArgs"></param>
        void IO_Completed(object sender, SocketAsyncEventArgs asyncEventArgs)
        {
            AsyncSocketUserToken userToken = asyncEventArgs.UserToken as AsyncSocketUserToken;

            userToken.ActiveDateTime = DateTime.Now;
            try
            {
                lock (userToken)
                {//避免同一个userToken同时有多个线程操作
                    if (asyncEventArgs.LastOperation == SocketAsyncOperation.Receive)
                    {
                        ProcessReceive(asyncEventArgs);
                    }
                    else if (asyncEventArgs.LastOperation == SocketAsyncOperation.Send)
                    {
                        ProcessSend(asyncEventArgs);
                    }
                    else
                    {
                        throw new ArgumentException("The last operation completed on the socket was not a receive or send");
                    }
                }
            }
            catch (Exception E)
            {
                LogHelper.Error(string.Format("IO_Completed {0} error, message: {1}", userToken.ConnectSocket, E.Message));
                LogHelper.Error(E.StackTrace);
            }
        }
예제 #3
0
 public void Remove(AsyncSocketUserToken userToken)
 {
     lock (m_list)
     {
         m_list.Remove(userToken);
     }
 }
예제 #4
0
 public void Add(AsyncSocketUserToken userToken)
 {
     lock (m_list)
     {
         m_list.Add(userToken);
     }
 }
예제 #5
0
 public void CopyList(ref AsyncSocketUserToken[] array)
 {
     lock (m_list)
     {
         array = new AsyncSocketUserToken[m_list.Count];
         m_list.CopyTo(array);
     }
 }
예제 #6
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="item"></param>
 public void Push(AsyncSocketUserToken item)
 {
     if (item == null)
     {
         throw new ArgumentException("Items added to a AsyncSocketUserToken cannot be null");
     }
     lock (m_pool)
     {//对m_asyncSocketUserTokenPool和m_asyncSocketUserTokenList进行处理的时候都有加锁
         m_pool.Push(item);
     }
 }
예제 #7
0
        public AsyncSocketInvokeElement(AsyncSocketServer asyncSocketServer, AsyncSocketUserToken asyncSocketUserToken)
        {
            m_asyncSocketServer    = asyncSocketServer;
            m_asyncSocketUserToken = asyncSocketUserToken;

            m_netByteOrder = false;

            m_sendAsync = false;

            m_connectDT = DateTime.UtcNow;
            m_activeDT  = DateTime.UtcNow;
        }
예제 #8
0
        /// <summary>
        /// 按照连接数建立读写对象
        /// </summary>
        public void Init()
        {
            AsyncSocketUserToken userToken;

            for (int i = 0; i < m_numConnections; i++)
            {
                userToken = new AsyncSocketUserToken(m_receiveBufferSize);
                userToken.ReceiveEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                userToken.SendEventArgs.Completed    += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                m_asyncSocketUserTokenPool.Push(userToken);
            }
        }
예제 #9
0
 public void SendCommand(AsyncSocketUserToken token, PoolCommand command)
 {
     try
     {
         var buffer = command.GetBytes();
         this.SendAsyncEvent(token.ConnectSocket, token.SendEventArgs, buffer, 0, buffer.Length);
     }
     catch (Exception ex)
     {
         LogHelper.Error(ex.Message, ex);
         this.CloseSocket(token);
     }
 }
예제 #10
0
        /// <summary>
        /// 发送事件响应函数,发送的逻辑,把发送数据放到一个列表中,当上一个发送事件完成响应Completed事件,
        /// 这时我们需要检测发送队列中是否存在未发送的数据,如果存在则继续发送
        /// </summary>
        /// <param name="sendEventArgs"></param>
        /// <returns></returns>
        private bool ProcessSend(SocketAsyncEventArgs sendEventArgs)
        {
            AsyncSocketUserToken userToken = sendEventArgs.UserToken as AsyncSocketUserToken;

            userToken.ActiveDateTime = DateTime.Now;
            if (sendEventArgs.SocketError == SocketError.Success)
            {
                return(true);
            }
            else
            {
                CloseSocket(userToken);
                return(false);
            }
        }
예제 #11
0
        private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs)
        {
            LogHelper.Info(string.Format("Client connection accepted. Local Address: {0}, Remote Address: {1}",
                                         acceptEventArgs.AcceptSocket.LocalEndPoint, acceptEventArgs.AcceptSocket.RemoteEndPoint));
            Interlocked.Increment(ref ConnectionCount);
            AsyncSocketUserToken userToken = m_asyncSocketUserTokenPool.Pop();

            m_asyncSocketUserTokenList.Add(userToken); //添加到正在连接列表
            userToken.ConnectSocket   = acceptEventArgs.AcceptSocket;
            userToken.ConnectDateTime = DateTime.Now;
            userToken.Address         = acceptEventArgs.AcceptSocket.RemoteEndPoint.ToString();

            if (this.ReceivedMinerConnectionAction != null)
            {
                this.ReceivedMinerConnectionAction(userToken, true);
            }

            try
            {
                bool willRaiseEvent = userToken.ConnectSocket.ReceiveAsync(userToken.ReceiveEventArgs); //投递接收请求
                if (!willRaiseEvent)
                {
                    lock (userToken)
                    {
                        ProcessReceive(userToken.ReceiveEventArgs);
                    }
                }
            }
            catch (Exception E)
            {
                LogHelper.Error(string.Format("Accept client {0} error, message: {1}", userToken.ConnectSocket, E.Message));
                LogHelper.Error(E.StackTrace);
            }

            StartAccept(acceptEventArgs); //把当前异步事件释放,等待下次连接
        }
예제 #12
0
        /// <summary>
        /// 接收事件响应函数,接收的逻辑
        /// </summary>
        /// <param name="receiveEventArgs"></param>
        private void ProcessReceive(SocketAsyncEventArgs receiveEventArgs)
        {
            AsyncSocketUserToken userToken = receiveEventArgs.UserToken as AsyncSocketUserToken;

            if (userToken.ConnectSocket == null)
            {
                return;
            }
            userToken.ActiveDateTime = DateTime.Now;
            if (userToken.ReceiveEventArgs.BytesTransferred > 0 && userToken.ReceiveEventArgs.SocketError == SocketError.Success)
            {
                HeartbeatCommand.UpdateHeartTime(userToken);

                int offset = userToken.ReceiveEventArgs.Offset;
                int count  = userToken.ReceiveEventArgs.BytesTransferred;

                if (count > 0) //处理接收数据
                {
                    var         buffer          = userToken.ReceiveEventArgs.Buffer;
                    var         commandDataList = new List <byte[]>();
                    var         index           = 0;
                    List <byte> bytes           = null;

                    while (index < buffer.Length)
                    {
                        if (bytes == null)
                        {
                            if ((index + 3) < buffer.Length &&
                                buffer[index] == PoolCommand.DefaultPrefixBytes[0] &&
                                buffer[index + 1] == PoolCommand.DefaultPrefixBytes[1] &&
                                buffer[index + 2] == PoolCommand.DefaultPrefixBytes[2] &&
                                buffer[index + 3] == PoolCommand.DefaultPrefixBytes[3])
                            {
                                bytes = new List <byte>();
                                bytes.AddRange(PoolCommand.DefaultPrefixBytes);
                                index += 4;
                            }
                            else
                            {
                                index++;
                            }
                        }
                        else
                        {
                            if ((index + 3) < buffer.Length &&
                                buffer[index] == PoolCommand.DefaultSuffixBytes[0] &&
                                buffer[index + 1] == PoolCommand.DefaultSuffixBytes[1] &&
                                buffer[index + 2] == PoolCommand.DefaultSuffixBytes[2] &&
                                buffer[index + 3] == PoolCommand.DefaultSuffixBytes[3])
                            {
                                bytes.AddRange(PoolCommand.DefaultSuffixBytes);
                                commandDataList.Add(bytes.ToArray());
                                bytes = null;

                                index += 4;
                            }
                            else
                            {
                                bytes.Add(buffer[index]);
                                index++;
                            }
                        }
                    }

                    if (this.ReceivedCommandAction != null)
                    {
                        foreach (var data in commandDataList)
                        {
                            try
                            {
                                var cmd = PoolCommand.ConvertBytesToMessage(data);
                                if (cmd != null)
                                {
                                    this.ReceivedCommandAction(userToken, cmd);
                                }
                            }
                            catch (Exception ex)
                            {
                                LogHelper.Warn($"Error Data from {userToken.Address}:{Base16.Encode(data)}");
                                LogHelper.Error("Error occured on deserialize messgae: " + ex.Message, ex);
                            }
                        }
                    }

                    if (userToken.ConnectSocket == null || userToken.ReceiveEventArgs == null)
                    {
                        return;
                    }

                    bool willRaiseEvent = userToken.ConnectSocket.ReceiveAsync(userToken.ReceiveEventArgs); //投递接收请求
                    if (!willRaiseEvent)
                    {
                        ProcessReceive(userToken.ReceiveEventArgs);
                    }
                }
                else
                {
                    CloseSocket(userToken);
                }
            }
        }