Exemple #1
0
        private void OnClientState(ClientBase client, bool isConnected)
        {
            ClientState?.Invoke(this, client, isConnected);

            if (!isConnected)
            {
                RemoveClient(client);
            }
        }
        /// <summary>
        /// 关闭socket客户端
        /// </summary>
        /// <param name="e"></param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            try
            {
                HCClient token = e.UserToken as HCClient;


                if (m_clientPool.Contains(e))
                {
                    //关闭与客户端连接的socket
                    try
                    {
                        token.Socket.Shutdown(SocketShutdown.Both);
                    }
                    catch (Exception)
                    {                                                           //客户端已经关闭
                    }
                    ClientState?.Invoke(HCClientStateEnmu.Disconnected, token); //客户端断开连接
                    token.Socket.Close();
                    token.ClearCache();

                    //连接数递减
                    Interlocked.Decrement(ref m_numConnectedSockets);

                    //释放SocketAsyncEventArgs,以便其他客户端可以重用它们
                    m_readPool.Push(e);
                    m_clientPool.Remove(e);

                    m_maxNumberAcceptedClients.Release();
                    Console.WriteLine("客户端从服务器断开连接,当前服务器客户端连接数:{0}",
                                      m_numConnectedSockets);
                }
                else
                {
                    Console.WriteLine("客户端从服务器断开连接");
                }
            }
            catch (Exception exp)
            {
                ServerState?.Invoke(HCServerStateEnmu.RunningException, exp.Message);
            }
        }
 /// <summary>
 /// 客户端接收到消息
 /// </summary>
 /// <param name="state"></param>
 /// <param name="msg"></param>
 private void HCServer_ClientDataState(HCDataStateEnmu state, HCMessage msg)
 {
     try
     {
         if (msg.ClientID == "")
         {                                                                   //没有客户端ID,解析ID
             string[] info = msg.GetDataString().Split(new string[] { "/" }, StringSplitOptions.None);
             string   ver  = info[0];                                        //协议版本号
             msg.ClientID          = info[1];                                //客户端ID
             msg.HCClient.ClientID = info[1];                                //客户端ID
             ClientState?.Invoke(HCClientStateEnmu.Connected, msg.HCClient); //客户端连接成功(业务逻辑上成功)
         }
         else
         {
             ClientDataState?.Invoke(state, msg);
         }
     }
     catch (Exception e)
     {
         ServerState?.Invoke(HCServerStateEnmu.RunningException, e.Message);
     }
 }
        /// <summary>
        /// 解析接收到的数据
        /// </summary>
        /// <param name="data"></param>
        public void AnalysisData(byte[] data)
        {
            try
            {
                Console.WriteLine("准备解析数据:");
                m_pingcount = 0;

                if (data.Length < 4)
                {
                    Console.WriteLine("解析数据的长度小于4个,数据进入缓冲区");
                    if (datacache.Count + data.Length < 4)
                    {//缓冲区与新添加的数据不够4个字节
                        Console.WriteLine("缓冲区已有数据与数据长度总长小于4,数据追加进入缓冲区,并准备接收下一次数据");
                        datacache.AddRange(data);
                        return;
                    }
                }

                if (datacache.Count == 0)
                {                                    //缓冲区没有数,需要处理的数据是带包头的
                    Console.WriteLine("缓冲区无数据,本次数据包含包头数据");
                    byte[] datalength = new byte[4]; //获取包头
                    Array.Copy(data, 0, datalength, 0, datalength.Length);
                    Console.WriteLine("输出包头" + datalength[0] + " " + datalength[1] + " " + datalength[2] + " " + datalength[3]);
                    Array.Reverse(datalength);                                 //倒转数据
                    uint packagelength = BitConverter.ToUInt32(datalength, 0); //读取到包的长度
                    Console.WriteLine("本次数据包长度为:" + packagelength + ";数据总长为:" + data.Length);

                    if (packagelength == (data.Length - 4))
                    {//恰好一个数据包
                        Console.WriteLine("恰好一个完整的数据包");
                        if (packagelength == 1)
                        {//ping包回馈
                            Console.WriteLine("ping包");
                        }
                        else
                        {
                            Console.WriteLine("非ping包,准备传递数据");
                            byte[] msgdata = new byte[packagelength];
                            Array.Copy(data, 4, msgdata, 0, msgdata.Length);
                            ClientDataState?.Invoke(HCDataStateEnmu.Received, new HCMessage(this, msgdata));
                        }
                    }
                    else if (packagelength < (data.Length - 4))
                    {//粘包情况
                        Console.WriteLine("粘包情况");
                        if (packagelength == 1)
                        {//ping包回馈
                            Console.WriteLine("粘包中的ping包");
                        }
                        else
                        {
                            Console.WriteLine("粘包中的非ping包,准备传递数据");
                            byte[] msgdata = new byte[packagelength];
                            Array.Copy(data, 4, msgdata, 0, msgdata.Length);
                            ClientDataState?.Invoke(HCDataStateEnmu.Received, new HCMessage(this, msgdata));
                        }

                        Console.WriteLine("继续处理剩下的粘包数据,长度:" + (data.Length - packagelength - 4));
                        byte[] datacontinue = new byte[data.Length - packagelength - 4];
                        Array.Copy(data, packagelength + 4, datacontinue, 0, datacontinue.Length);

                        Console.WriteLine("继续处理的粘包数据头:" + data[packagelength] + " " + data[packagelength + 1] +
                                          " " + data[packagelength + 2] + " " + data[packagelength + 3]);
                        AnalysisData(datacontinue);
                    }
                    else
                    {//半包情况
                        Console.WriteLine("半包情况");
                        datacache.AddRange(data);
                        if (packagelength <= datacache.Count - 4)
                        {//缓冲区中数据可形成整包
                            Console.WriteLine("缓冲区中数据可形成整包,继续解析数据");
                            byte[] datacontinue = datacache.ToArray();
                            datacache.Clear();
                            AnalysisData(datacontinue);
                        }
                    }
                }
                else
                {//缓冲区有数据,接收到的数据是没有包头的
                    Console.WriteLine("缓冲区有数据,接收到的数据是没有包头的");
                    datacache.AddRange(data);
                    byte[] datacontinue = datacache.ToArray();
                    datacache.Clear();
                    AnalysisData(datacontinue);
                }
            }
            catch (Exception exp)
            {
                ClientState?.Invoke(HCClientStateEnmu.RunningException, this);
            }
        }
Exemple #5
0
 private void OnClientState(Client client, bool isConnected) => ClientState?.Invoke(this, client, isConnected);