예제 #1
0
        //关闭连接进来的Socket
        public void CloseClientSocket(UserTokenEventArgs userToken)
        {
            if (userToken != null)
            {
                if (userToken.Socket == null)
                {
                    return;
                }
                try
                {
                    if (this.customizeHander != null && !userToken.CurrentUserID.IsNullEmpty())
                    {
                        customizeHander.ClientClose(userToken, userToken.CurrentUserID);
                    }

                    EventHandler <UserTokenEventArgs> handler = OnClientDisconnect;   // 如果订户事件将为空(null)
                    if ((handler != null) && userToken.Socket != null)
                    {
                        handler(this, userToken);//抛出连接断开事件
                    }
                    if (userToken.Socket.Connected)
                    {
                        userToken.Socket.Shutdown(SocketShutdown.Both);
                    }
                    userToken.Socket.Close();
                    userToken.Socket = null;
                    userToken.SetInit();
                    this.maxNumberAcceptedClients.Release();
                    lock (recvStackPool)
                    {
                        recvStackPool.Push(userToken.ReceiveSocketAsyncEventArgs);  // 释放以使它们可以被其他客户端重新利用,总数不变
                    }
                }
                // 抛出客户处理已经被关闭
                catch (ObjectDisposedException)
                {
                    Console.WriteLine("关闭对象已经被释放");
                }
                catch (SocketException)
                {
                }
                catch (Exception exception_debug)
                {
                    Console.WriteLine("关闭Socket调试:" + exception_debug.ToString());
                    //throw exception_debug;
                }
                finally
                {
                    if (connectedSocketsCount > 0) //减少连接到服务器的socket计数器
                    {
                        Interlocked.Decrement(ref connectedSocketsCount);
                    }
                    //this.UserDic.RemoveByValue(userToken);
                    if (!userToken.CurrentUserID.IsNullEmpty())
                    {
                        this.UserDic.Remove(userToken.CurrentUserID);
                    }
                }
            }
        }
예제 #2
0
        private void ProcessAcceptConnect(SocketAsyncEventArgs e) //真正处理连接进来的socket
        {
            if (e.LastOperation != SocketAsyncOperation.Accept)   //检查上一次操作是否是Accept,不是就返回
            {
                return;
            }
            if (e.SocketError == SocketError.Success)
            {
                Socket sock = e.AcceptSocket;
                if (sock != null && sock.Connected)
                {
                    Interlocked.Increment(ref this.connectedSocketsCount);
                    SocketAsyncEventArgs tempAgrs  = this.recvStackPool.Pop();
                    UserTokenEventArgs   userToken = tempAgrs.UserToken as UserTokenEventArgs;
                    try
                    {
                        userToken.ConnectTime = DateTime.Now;
                        userToken.ActiveTime  = DateTime.Now;
                        userToken.Socket      = sock;

                        if (!userToken.Socket.ReceiveAsync(userToken.ReceiveSocketAsyncEventArgs))
                        {
                            this.ProcessReceive(userToken.ReceiveSocketAsyncEventArgs);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.RaiseErrorEvent(userToken, ex);
                    }
                    this.StartAcceptRequset(e);
                }
            }
        }
예제 #3
0
 //抛出错误事件
 private void RaiseErrorEvent(UserTokenEventArgs token, Exception exception)
 {
     if (OnClientError != null)
     {
         if (null != token)
         {
             OnClientError(token, new SocketServerErrorEventArgs(exception));//抛出客户端错误事件
         }
         else
         {
             OnClientError(null, new SocketServerErrorEventArgs(exception));//抛出服务器错误事件
         }
     }
 }
예제 #4
0
        /// <summary>
        /// 这个方法当一个异步发送操作完成时被调用.
        /// </summary>
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            UserTokenEventArgs userToken = (UserTokenEventArgs)e.UserToken;

            // 回收SocketAsyncEventArgs以备再次被利用
            //Interlocked.Add(ref sendTotalBytes, e.BytesTransferred); // 增加发送的字节总数
            lock (sendStackPool)
            {
                sendStackPool.Push(userToken.SendSocketAsyncEventArgs);
            }
            // 清除UserToken对象引用
            e.UserToken = null;
            if (e.SocketError == SocketError.Success)
            {
                //发送完成后做清除,抛出事件等操作 这里暂时什么都不做
            }
            else
            {
                CloseClientSocket(userToken);
            }
        }
예제 #5
0
        public event EventHandler <SocketServerErrorEventArgs> OnClientError; // 客户端错误事件

        // public event EventHandler<AsyncSocketUserToken> OnDataSendCompleted; // 数据发送完成

        #endregion
        public SocketServer(int maxConnectionCount)
        {
            this.MaxConnectionCount = maxConnectionCount;
            this.recvStackPool      = new SocketAsyncEventArgsStackPool(maxConnectionCount);//初始化对象池
            this.sendStackPool      = new SocketAsyncEventArgsStackPool(maxConnectionCount);
            this.UserDic            = new ObjectManager <string, UserTokenEventArgs>();
            UserTokenEventArgs userToken;

            for (int i = 0; i <= maxConnectionCount; i++) //按照连接数建立读写对象
            {
                userToken = new UserTokenEventArgs(this.receiveBufferSize);
                userToken.ReceiveSocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                userToken.SendSocketAsyncEventArgs.Completed    += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                recvStackPool.Push(userToken.ReceiveSocketAsyncEventArgs);//把userToken的SocketAsyncEventArgs装入对象池
                sendStackPool.Push(userToken.SendSocketAsyncEventArgs);
            }
            maxNumberAcceptedClients = new Semaphore(maxConnectionCount, maxConnectionCount); // 初始信号量

            tCheckClientHeartbeat = new Thread(CheckClientHeartbeat);                         //开启新线程检查心跳
            tCheckClientHeartbeat.IsBackground = true;
            tCheckClientHeartbeat.Start();
        }
예제 #6
0
        public void Send(string connectionId, byte[] buffer)
        {
            UserTokenEventArgs userToken = UserDic.Get(connectionId);

            if (userToken == null || userToken.Socket == null)
            {
                return;
            }
            if (userToken.ClientType == ClientType.WebSocket)
            {
                buffer = WebSocketUtils.PackServerData(buffer);//或者使用DataFram
            }
            SocketAsyncEventArgs sendEventArgs = null;

            lock (sendStackPool)
            {
                sendEventArgs = sendStackPool.Pop();
            }
            if (sendEventArgs != null && sendEventArgs.SocketError == SocketError.Success)
            {
                sendEventArgs.UserToken = userToken;
                sendEventArgs.SetBuffer(buffer, 0, buffer.Length);//最后设置发送数据
                try
                {
                    //异步发送数据
                    //Array.Copy(buffer, 0, sendEventArgs.Buffer, 0, buffer.Length);//设置发送数据
                    bool willRaiseEvent = userToken.Socket.SendAsync(sendEventArgs);//采用异步发送才能处理sendStackPool
                    if (!willRaiseEvent)
                    {
                        ProcessSend(sendEventArgs);
                    }
                }
                catch (Exception ex)
                {
                    RaiseErrorEvent(userToken, ex);
                    Console.WriteLine("Send调试" + ex.ToString());
                }
            }
        }
예제 #7
0
        private bool ProcessPacket(UserTokenEventArgs userToken)
        {
            if (userToken.ClientType != ClientType.WebSocket)//第一次进来握手操作
            {
                byte[]             info      = userToken.bufferManager.GetCopyBuffer();
                WebSocketHandshake handshake = new WebSocketHandshake(info);
                if (handshake.IsWebSocket)
                {
                    userToken.Socket.Send(Encoding.UTF8.GetBytes(handshake.Response));
                    userToken.bufferManager.Reset();
                    userToken.ClientType = ClientType.WebSocket;
                    handshake            = null;
                    return(true);
                }
            }

            if (userToken.ClientType == ClientType.WebSocket)
            {
                int bodyLen         = 0;
                int informationType = -1;
                #region 处理WebSocket
                while (userToken.ResvBufferManager.Length > 6)
                {
                    if (userToken.ResvBufferManager.Length % this.receiveBufferSize == 0) //客户端一次发送的数据大于服务端缓冲区
                    {
                        return(true);
                    }
                    if (userToken.ResvBufferManager.Length >= 1024 * 120)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("单个包发送不能大于120K"));
                        return(false);
                    }
                    int clearCount = 0;

                    DataFrame dr = new DataFrame(userToken.ResvBufferManager.Buffer, ref clearCount);
                    if (dr.Header.OpCode == OpCode.Close)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("用户主动断开"));
                        return(false);
                    }
                    if (dr.Header.OpCode == OpCode.Binary)
                    {
                        #region 正常解析为二进制

                        byte[] hasAnalyzeData = dr.BinaryContent;
                        bodyLen = BitConverter.ToInt32(hasAnalyzeData, 0);              //包长
                        if (userToken.ResvBufferManager.Length >= bodyLen + clearCount) //包足够的情况
                        {
                            informationType = BitConverter.ToInt16(hasAnalyzeData, 4);  //消息类型
                            if (informationType > Int16.MaxValue || informationType < 0 || bodyLen > this.maxPacketLength | userToken.ResvBufferManager.Length > this.maxPacketLength)
                            {
                                this.RaiseErrorEvent(userToken, new Exception("解析消息类型错误|包长度超过最大长度"));
                                return(false);
                            }
                            if (informationType == 998)
                            {
                                int userIdLen = hasAnalyzeData[6];
                                if (userIdLen > this.maxUserIdlength)
                                {
                                    this.RaiseErrorEvent(userToken, new Exception("UserId长度过长"));
                                    return(false);
                                }
                                string userId    = Encoding.UTF8.GetString(BytesHelper.CopyArrayData(hasAnalyzeData, 7, this.maxUserIdlength)).Replace("\0", "");
                                string failCause = string.Empty;
                                if (this.customizeHander != null && !customizeHander.CheckLoginUser("ABC", userId, "", out failCause))
                                {
                                    this.RaiseErrorEvent(userToken, new Exception(failCause));
                                    return(false);
                                }
                                this.UserDic.Add(userId, userToken);//添加登录用户才可以发送
                                userToken.ConnectedId = userId;
                                userToken.SendBufferManager.WriteInt16((short)informationType);
                                userToken.SendBufferManager.WriteString0(failCause);
                                this.Send(userId, userToken.SendBufferManager.GetCopyBuffer());
                                Console.WriteLine(string.Format("用户{0}登录成功---" + DateTime.Now, userId));
                                userToken.ResvBufferManager.Reset();
                                userToken.SendBufferManager.Reset();
                            }
                            else
                            {
                                if (string.IsNullOrEmpty(userToken.ConnectedId))
                                {
                                    this.RaiseErrorEvent(userToken, new Exception(string.Format("用户{0}未登录;InfomationType:{1}", userToken.UserSocket.RemoteEndPoint, informationType)));
                                    return(false);
                                }
                                if (hasAnalyzeData.Length < bodyLen)
                                {
                                    Console.WriteLine("***********************" + bodyLen);
                                    userToken.ResvBufferManager.Clear(clearCount);
                                    //return true;
                                }

                                byte[] content = BytesHelper.CopyArrayData(hasAnalyzeData, 6, hasAnalyzeData.Length - 6);
                                if (this.customizeHander != null)
                                {
                                    customizeHander.HandleInformation(userToken, userToken.ConnectedId, informationType, content);
                                }

                                // Console.WriteLine(" FBL:" + userToken.bufferManager.Length + " BOdyLen:" + bodyLen + " HL:" + hasAnalyzeData.Length + " clearCount:" + clearCount);
                                userToken.ResvBufferManager.Clear(bodyLen + clearCount);
                            }
                        }
                        else
                        {
                            return(true);
                        }

                        #endregion
                    }
                    else
                    {
                        Console.WriteLine("OP:" + dr.Header.OpCode + "____出现此错误可能包长度不对");
                        userToken.ResvBufferManager.Reset(true);
                        return(true);
                    }
                }
                #endregion
            }
            if (userToken.ClientType == ClientType.DotNET)//继续处理其他平台
            {
            }
            return(true);
        }
예제 #8
0
        /// <summary>
        /// 异步接收操作完成时调用.   如果远程主机关闭连接Socket将关闭
        /// </summary>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            UserTokenEventArgs userToken = e.UserToken as UserTokenEventArgs;

            if (userToken == null || userToken.Socket == null)
            {
                return;
            }
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success && userToken.Socket.Connected) // 检查远程主机是否关闭连接
            {
                Interlocked.Add(ref receiveTotalBytes, e.BytesTransferred);                                   // 增加接收到的字节总数
                userToken.ActiveTime = DateTime.Now;                                                          //重置活动时间
                if (userToken.Socket.Available == 0)                                                          //判断所有需接收的数据是否已经完成
                {
                    //从侦听者获取接收到的消息。
                    byte[] data = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, data, 0, data.Length);//从e.Buffer块中复制数据出来,保证它可重用
                    userToken.bufferManager.WriteBuffer(data);
                }
                try
                {
                    if (!this.ProcessPacket(userToken))//如果处理数据返回失败,则断开连接
                    {
                        CloseClientSocket(userToken);
                    }
                    else
                    {
                        EventHandler <UserTokenEventArgs> handler = OnClientRead;// 抛出接收到数据事件
                        if (handler != null)
                        {
                            handler(this, userToken);
                        }
                        // 继续接收数据
                        bool willRaiseEvent = userToken.Socket.ReceiveAsync(userToken.ReceiveSocketAsyncEventArgs); //投递接收请求
                        if (!willRaiseEvent)
                        {
                            ProcessReceive(userToken.ReceiveSocketAsyncEventArgs);
                        }
                    }
                }
                catch (ObjectDisposedException)
                {
                    CloseClientSocket(userToken);
                }
                catch (SocketException socketException)
                {
                    if (socketException.ErrorCode == (int)SocketError.ConnectionReset) //10054一个建立的连接被远程主机强行关闭
                    {
                        CloseClientSocket(userToken);                                  //引发断开连接事件
                    }
                    else
                    {
                        RaiseErrorEvent(userToken, new Exception("在SocketAsyncEventArgs对象上执行异步接收数据操作时发生SocketException异常", socketException));
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ProcessReceive调试" + ex.ToString());
                }
            }
            else
            {
                CloseClientSocket(userToken);
            }
            Console.WriteLine("已连接数:" + this.connectedSocketsCount + "__LoginUserDic数:" + UserDic.Count + "--接收Stack数:" + this.recvStackPool.Count + "--发送Stack数:" + this.sendStackPool.Count);
        }