/// <summary>
        /// 发送完成时处理函数
        /// </summary>
        /// <param name="e">与发送完成操作相关联的SocketAsyncEventArg对象</param>
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                AsyncUserToken token = (AsyncUserToken)e.UserToken;
                Socket         s     = (Socket)token.Socket;

                //TODO
                token.ActiveDateTime = DateTime.Now;
            }
            else
            {
                CloseClientSocket(e);
            }
        }
        /// <summary>
        /// 监听Socket接受处理
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed accept operation.</param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                Socket s = e.AcceptSocket;//和客户端关联的socket
                if (s != null && s.Connected)
                {
                    try
                    {
                        Interlocked.Increment(ref _clientCount);//原子操作加1
                        SocketAsyncEventArgs asyniar = _objectPool.Pop();
                        AsyncUserToken       token   = (AsyncUserToken)asyniar.UserToken;

                        //用户的token操作
                        token.Socket          = s;
                        token.ID              = System.Guid.NewGuid().ToString();
                        token.ConnectDateTime = DateTime.Now;

                        SocketUserTokenList.Add(asyniar); //添加到正在连接列表

                        s.Send(Encoding.UTF8.GetBytes("Your GUID:" + token.ID));

                        Log4Debug(String.Format("客户 {0} 连入, 共有 {1} 个连接。", s.RemoteEndPoint.ToString(), _clientCount));

                        if (!s.ReceiveAsync(asyniar))//投递接收请求
                        {
                            ProcessReceive(asyniar);
                        }
                    }
                    catch (SocketException ex)
                    {
                        Log4Debug(String.Format("接收客户 {0} 数据出错, 异常信息: {1} 。", s.RemoteEndPoint, ex.ToString()));
                        //TODO 异常处理
                    }
                    //投递下一个接受请求
                    StartAccept(e);
                }
            }
            else
            {
                CloseClientSocket(e);;
            }
        }
예제 #3
0
        public void DaemonThreadStart()
        {
            while (m_thread.IsAlive)
            {
                SocketAsyncEventArgs[] userTokenArray = null;
                m_asyncSocketServer.SocketUserTokenList.CopyList(ref userTokenArray);
                for (int i = 0; i < userTokenArray.Length; i++)
                {
                    if (!m_thread.IsAlive)
                    {
                        break;
                    }
                    try
                    {
                        AsyncUserToken userToke = userTokenArray[i].UserToken as AsyncUserToken;
                        if ((DateTime.Now - userToke.ActiveDateTime).Milliseconds > m_asyncSocketServer.SocketTimeOutMS) //超时Socket断开
                        {
                            lock (userTokenArray[i])
                            {
                                m_asyncSocketServer.CloseClientSocket(userTokenArray[i]);
                            }
                        }
                    }
                    catch (Exception E)
                    {
                        Log4Debug(string.Format("Daemon thread check timeout socket error, message: {0}", E.Message));
                        Log4Debug(E.StackTrace);
                    }
                }

                for (int i = 0; i < 60 * 1000 / 10; i++) //每分钟检测一次
                {
                    if (!m_thread.IsAlive)
                    {
                        break;
                    }
                    Thread.Sleep(10);
                }
            }
        }
        /// <summary>
        /// 关闭socket连接
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed send/receive operation.</param>
        public void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            if (token == null)
            {
                e.AcceptSocket.Close();
                _maxAcceptedClients.Release();//释放线程信号量
                return;
            }

            if (e.SocketError == SocketError.OperationAborted || e.SocketError == SocketError.ConnectionAborted)
            {
                return;
            }

            Log4Debug(String.Format("客户 {0} 断开连接!", token.Socket.RemoteEndPoint.ToString()));
            //删除已经连接的东西
            //dt.socketlist.Remove(token);

            Socket s = token.Socket as Socket;

            CloseClientSocket(s, e);
        }
        /// <summary>
        ///接收完成时处理函数
        /// </summary>
        /// <param name="e">与接收完成操作相关联的SocketAsyncEventArg对象</param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)//if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                // 检查远程主机是否关闭连接
                if (e.BytesTransferred > 0)
                {
                    AsyncUserToken token = (AsyncUserToken)e.UserToken;
                    token.ActiveDateTime = DateTime.Now;
                    Socket s = (Socket)token.Socket;
                    //判断所有需接收的数据是否已经完成
                    if (s.Available == 0)
                    {
                        //从侦听者获取接收到的消息。
                        //String received = Encoding.ASCII.GetString(e.Buffer, e.Offset, e.BytesTransferred);
                        //echo the data received back to the client
                        //e.SetBuffer(e.Offset, e.BytesTransferred);

                        byte[] data = new byte[e.BytesTransferred];
                        Array.Copy(e.Buffer, e.Offset, data, 0, data.Length);//从e.Buffer块中复制数据出来,保证它可重用

                        string info = Encoding.Default.GetString(data);
                        Log4Debug(String.Format("收到 {0} 数据为 {1}", s.RemoteEndPoint.ToString(), info));
                        //TODO 处理数据 ,区分数据是否是转发 ,也可以处理成广播
                        //IPEndPoint iep1 = new IPEndPoint(IPAddress.Any, 12030);
                        //s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                        //s.SendTo(data, iep1);

                        //if (info == "Listens_all")
                        //{
                        //    try
                        //    {
                        //        //pc端的用户,存进全局列表
                        //        dt.socketlist.Add(token);
                        //    }
                        //    catch { }
                        //}
                        //else
                        //{
                        //    //遍历pc端登陆的客户端,并发送消息
                        //    for (int i = 0; i < dt.socketlist.Count; i++)
                        //    {
                        //        try
                        //        {
                        //            Socket tmp = ((AsyncUserToken)dt.socketlist[i]).Socket;
                        //            tmp.Send(data);
                        //        }
                        //        catch { }

                        //    }
                        //}
                        //增加服务器接收的总字节数。
                    }

                    if (!s.ReceiveAsync(e))//为接收下一段数据,投递接收请求,这个函数有可能同步完成,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
                    {
                        //同步接收时处理接收完成事件
                        ProcessReceive(e);
                    }
                }
                else
                {
                    CloseClientSocket(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }