Exemple #1
0
        public event EventHandler <UserTokenEventArgs> OnDataSendCompleted; // 数据发送完成

        #endregion
        public SocketServer(int maxConnectionCount)
        {
            this.MaxConnectionCount = maxConnectionCount;
            this.UserDic            = new ObjectManager <string, UserTokenEventArgs>();

            for (int i = 0; i <= maxConnectionCount; i++) //按照连接数建立读写对象
            {
                byte[]             receiveBuffer = new byte[receiveBufferSize];
                UserTokenEventArgs userToken     = new UserTokenEventArgs();

                userToken.RecvSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBufferSize);
                userToken.RecvSocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                recvStackPool.Push(userToken.RecvSocketAsyncEventArgs);

                SocketAsyncEventArgs sendSocketAsyncEventArgs = new SocketAsyncEventArgs();
                sendSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBufferSize);
                sendSocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                sendStackPool.Push(sendSocketAsyncEventArgs);
            }
            maxNumberAcceptedClients = new Semaphore(maxConnectionCount, maxConnectionCount); // 初始信号量

            tCheckClientHeartbeat = new Thread(CheckClientHeartbeat);                         //开启新线程检查心跳
            tCheckClientHeartbeat.IsBackground = true;
            tCheckClientHeartbeat.Start();
        }
Exemple #2
0
 private void ProcessAccept(SocketAsyncEventArgs e)
 {
     if (e.LastOperation != SocketAsyncOperation.Accept)    //检查上一次操作是否是Accept,不是就返回
     {
         return;
     }
     if (e.SocketError == SocketError.Success)
     {
         Socket sock = e.AcceptSocket;
         if (sock != null && sock.Connected)
         {
             SocketAsyncEventArgs recvSocketAsyncEventArgs = null;
             if (this.recvStackPool.TryPop(out recvSocketAsyncEventArgs))
             {
                 UserTokenEventArgs userToken = recvSocketAsyncEventArgs.UserToken as UserTokenEventArgs;
                 userToken.ConnectTime = DateTime.Now;
                 userToken.ActiveTime  = DateTime.Now;
                 userToken.UserSocket  = sock;
                 Interlocked.Increment(ref this.connectedSocketsCount);
                 // 获得一个新的Guid 32位 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                 userToken.ConnectedId = Guid.NewGuid().ToString("N");
                 try
                 {
                     this.UserDic.Add(userToken.ConnectedId, userToken);// 添加到集合中
                     EventHandler <UserTokenEventArgs> handler = OnClientConnect;
                     if (handler != null)
                     {
                         handler(this, userToken);//抛出连接断开事件
                     }
                     if (!userToken.UserSocket.ReceiveAsync(recvSocketAsyncEventArgs))
                     {
                         ProcessReceive(recvSocketAsyncEventArgs);
                     }
                 }
                 catch (Exception ex)
                 {
                     this.RaiseErrorEvent(userToken, ex);
                     this.RaiseDisconnectedEvent(userToken);
                 }
             }
             else
             {
                 sock.Send(Encoding.Default.GetBytes("连接已经达到最大数!")); //已经达到最大客户连接数量,在这接受连接,发送“连接已经达到最大数”,然后断开连接
                 string outStr = String.Format("连接已满,拒绝 {0} 的连接。", sock.RemoteEndPoint);
                 RaiseErrorEvent(null, new Exception(outStr));
                 sock.Close();
             }
         }
         StartAccept(e);//投递接收请求
     }
 }
Exemple #3
0
 //抛出错误事件
 public void RaiseErrorEvent(UserTokenEventArgs token, Exception ex)
 {
     if (OnClientError != null)
     {
         if (null != token)
         {
             OnClientError(token, ex);//抛出客户端错误事件
         }
         else
         {
             OnClientError(null, ex);
         }
     }
 }
Exemple #4
0
        public void RaiseDisconnectedEvent(UserTokenEventArgs userToken)//引发断开连接事件
        {
            if (null != userToken && userToken.UserSocket != null)
            {
                try
                {
                    EventHandler <UserTokenEventArgs> handler = OnClientDisconnect;//最先抛出事件
                    // 如果订户事件将为空(null)
                    if (handler != null)
                    {
                        handler(this, userToken);//抛出连接断开事件
                    }
                    if (this.customizeHander != null && !userToken.ConnectedId.IsNullEmpty())
                    {
                        customizeHander.ClientClose(userToken);
                    }
                    userToken.Reset();//方便下一次使用

                    if (userToken.UserSocket.Connected)
                    {
                        try
                        {
                            userToken.UserSocket.Shutdown(SocketShutdown.Both);
                        }
                        catch { }
                    }

                    userToken.UserSocket.Close();
                    userToken.UserSocket = null;
                    Interlocked.Decrement(ref connectedSocketsCount);
                    maxNumberAcceptedClients.Release();
                    this.UserDic.Remove(userToken.ConnectedId);
                    recvStackPool.Push(userToken.RecvSocketAsyncEventArgs);// 释放以使它们可以被其他客户端重新利用,总数不变
                }
                catch (ObjectDisposedException)
                {
                    // 抛出客户处理已经被关闭
                }
                catch (Exception ex)
                {
                    RaiseErrorEvent(userToken, ex);
                }
                finally
                {
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// 异步接收操作完成时调用.   如果远程主机关闭连接Socket将关闭
        /// </summary>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            UserTokenEventArgs userToken = e.UserToken as UserTokenEventArgs;

            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                //Console.WriteLine("收到长度" + e.BytesTransferred + "  是否接受完毕" + userToken.UserSocket.Available);
                Interlocked.Add(ref receiveTotalBytes, e.BytesTransferred); // 增加接收到的字节总数
                userToken.ActiveTime = DateTime.Now;                        //重置活动时间
                userToken.ResvBufferManager.WriteBuffer(e.Buffer, e.Offset, e.BytesTransferred);
                try
                {
                    EventHandler <UserTokenEventArgs> handler = OnClientRead;// 抛出接收到数据事件
                    if (handler != null)
                    {
                        handler(this, userToken);
                    }
                    if (!this.ProcessPacket(userToken))//如果处理数据返回失败,则断开连接 使用内置的处理
                    {
                        RaiseDisconnectedEvent(userToken);
                    }
                    else
                    {
                        if (userToken.UserSocket != null && userToken.UserSocket.Connected)
                        {
                            bool willRaiseEvent = userToken.UserSocket.ReceiveAsync(e); //投递接收请求
                            if (!willRaiseEvent)
                            {
                                ProcessReceive(e);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    RaiseErrorEvent(userToken, ex);
                    RaiseDisconnectedEvent(userToken);
                }
            }
            else
            {
                RaiseDisconnectedEvent(userToken);
            }
        }
Exemple #6
0
        public void Send(string connectionId, byte[] buffer)
        {
            UserTokenEventArgs userToken = UserDic.Get(connectionId);

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

            if (this.sendStackPool.TryPop(out sendEventArgs))
            {
                try
                {
                    sendEventArgs.UserToken = userToken;
                    sendEventArgs.SetBuffer(buffer, 0, buffer.Length);//最后设置发送数据
                    //异步发送数据
                    //Array.Copy(buffer, 0, sendEventArgs.Buffer, 0, buffer.Length);//设置发送数据
                    bool willRaiseEvent = userToken.UserSocket.SendAsync(sendEventArgs);//采用异步发送才能处理sendStackPool
                    if (!willRaiseEvent)
                    {
                        ProcessSend(sendEventArgs);
                    }
                }
                catch (ObjectDisposedException)//调用此处的异步发送可能socket被其他进程关闭异常
                {
                    RaiseDisconnectedEvent(userToken);
                }
                catch (Exception ex)
                {
                    RaiseErrorEvent(userToken, ex);
                    RaiseDisconnectedEvent(userToken);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// 这个方法当一个异步发送操作完成时被调用.
        /// </summary>
        private void ProcessSend(SocketAsyncEventArgs e)
        {
            UserTokenEventArgs userToken = e.UserToken as UserTokenEventArgs;

            userToken.ActiveTime = DateTime.Now;
            Interlocked.Add(ref sendTotalBytes, e.BytesTransferred); // 增加发送的字节总数
            // 回收SocketAsyncEventArgs以备再次被利用
            userToken.SendBufferManager.Reset();
            e.UserToken = null; // 清除UserToken对象引用
            this.sendStackPool.Push(e);
            if (e.SocketError == SocketError.Success)
            {
                //发送完成后做清除,抛出事件等操作 这里暂时什么都不做
                EventHandler <UserTokenEventArgs> handler = OnDataSendCompleted;
                if (handler != null)
                {
                    handler(this, userToken);//抛出客户端发送完成事件
                }
            }
            else
            {
                RaiseDisconnectedEvent(userToken);
            }
        }
Exemple #8
0
        private bool ProcessPacket(UserTokenEventArgs userToken)
        {
            if (userToken.ClientType != ClientType.WebSocket)//第一次进来握手操作
            {
                byte[]             recvMsg   = userToken.ResvBufferManager.GetCopyBuffer();
                WebSocketHandshake handshake = new WebSocketHandshake(recvMsg);
                if (handshake.IsWebSocket)
                {
                    userToken.UserSocket.Send(Encoding.UTF8.GetBytes(handshake.Response));
                    userToken.ResvBufferManager.Reset();
                    userToken.ClientType = ClientType.WebSocket;
                }
                handshake = null;
                return(true);
            }
            if (userToken.ClientType == ClientType.WebSocket)
            {
                #region 处理WebSocket
                try
                {
                    if (userToken.ResvBufferManager.Length % this.receiveBufferSize == 0) //客户端一次发送的数据大于服务端缓冲区
                    {
                        return(true);
                    }
                    if (userToken.ResvBufferManager.Length >= 1024 * 120)
                    {
                        this.RaiseErrorEvent(userToken, new Exception("WebSocket暂不能解析大于120K的单个包"));
                        return(false);
                    }
                    while (userToken.ResvBufferManager.Length != 0)
                    {
                        int       clearCount = 0;
                        DataFrame dr         = new DataFrame(userToken.ResvBufferManager.Buffer, ref clearCount);
                        if (dr.Header.OpCode == OpCode.Close)
                        {
                            this.RaiseErrorEvent(userToken, new Exception("33333333333用户主动断开"));
                            return(false);
                        }
                        if (dr.Header.OpCode == OpCode.Binary)
                        {
                            #region 正常解析为二进制


                            MessageHeader header = new MessageHeader();
                            header.ProccessHeader(dr.BinaryContent);
                            if (header.MessageId > UInt16.MaxValue || header.MessageId < 0 || header.PacketLength > this.maxPacketLength | userToken.ResvBufferManager.Length > this.maxPacketLength)
                            {
                                this.RaiseErrorEvent(userToken, new Exception("解析消息类型错误|包长度超过最大长度"));
                                return(false);
                            }
                            if (userToken.ResvBufferManager.Length < header.PacketLength + clearCount)//包不足够的情况
                            {
                                return(true);
                            }
                            byte[]     content    = BytesHelper.CopyArrayData(dr.BinaryContent, header.Length, dr.BinaryContent.Length - header.Length);
                            NetMessage netMessage = new NetMessage(header, content);
                            userToken.NetMessage = netMessage;
                            //userToken.ResvBufferManager.SetOffset(header.Length-1);
                            if (this.customizeHander != null)
                            {
                                customizeHander.HandleInformation(userToken);
                                //customizeHander.HandleInformation(userToken, userToken.ConnectedId, netMessage.Header.MessageId, content);
                            }
                            userToken.ResvBufferManager.Clear(header.PacketLength + clearCount);
                            #endregion
                        }
                        else
                        {
                            this.RaiseErrorEvent(userToken, new Exception("WebScoket未能正确解析包 OP代码" + dr.Header.OpCode));
                            userToken.ResvBufferManager.Reset();
                            return(true);
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.RaiseErrorEvent(userToken, new Exception("处理WebSocket包出现异常:" + ex.ToString()));
                    return(false);
                }
                #endregion
            }
            if (userToken.ClientType == ClientType.DotNET)//继续处理其他平台
            {
                //string userId = userToken.UserSocket.RemoteEndPoint.ToString();
            }
            return(true);
        }