Exemple #1
0
        //关闭客户端
        void CloseClientSocketEx(SocketAsyncEventArgs e, SocketColseType colseType)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            if (token != null)
            {
                if (token.Socket != null && token.Socket.Connected)
                {
                    token.Socket.Shutdown(SocketShutdown.Both);
                    token.Socket.Close();
                }
            }
            onSocketClose(token.ConnId, colseType);
            semaphore.Release();
            lock (m_pool)
            {
                if (m_pool.Count < m_maxConnectNum)
                {
                    e.UserToken = new AsyncUserToken();
                    m_pool.Push(e);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// 发送数据方法
        /// </summary>
        /// <param name="socket">客户端socket</param>
        /// <param name="message">要发送的数据</param>
        bool WebSocketSend(AsyncUserToken token, string message)
        {
            var socket = token.Socket;

            byte[] bytes     = Comm.StringToBytes(message);
            bool   send      = true;
            int    SendMax   = bufferSize; //每次分片最大1kb数据
            int    count     = 0;          //发送的次数
            int    sendedlen = 0;          //已经发送的字节长度

            while (send)
            {
                byte[] contentBytes = null;//待发送的消息内容
                var    sendArr      = bytes.Skip(count * SendMax).Take(SendMax).ToArray();
                sendedlen += sendArr.Length;
                if (sendArr.Length > 0)
                {
                    send = bytes.Length > sendedlen;//是否继续发送
                    if (sendArr.Length < 126)
                    {
                        contentBytes    = new byte[sendArr.Length + 2];
                        contentBytes[0] = (byte)(count == 0 ? 0x81 : (!send ? 0x80 : 0));
                        contentBytes[1] = (byte)sendArr.Length;//1个字节存储真实长度
                        Array.Copy(sendArr, 0, contentBytes, 2, sendArr.Length);
                        send = false;
                    }
                    else if (sendArr.Length <= 65535)
                    {
                        contentBytes = new byte[sendArr.Length + 4];
                        if (!send && count == 0)
                        {
                            contentBytes[0] = 0x81;//非分片发送
                        }
                        else
                        {
                            contentBytes[0] = (byte)(count == 0 ? 0x01 : (!send ? 0x80 : 0));//处于连续的分片发送
                        }
                        contentBytes[1] = 126;
                        byte[] slen = BitConverter.GetBytes((short)sendArr.Length);//2个字节存储真实长度
                        contentBytes[2] = slen[1];
                        contentBytes[3] = slen[0];
                        Array.Copy(sendArr, 0, contentBytes, 4, sendArr.Length);
                    }
                    else if (sendArr.LongLength < long.MaxValue)
                    {
                        contentBytes    = new byte[sendArr.Length + 10];
                        contentBytes[0] = (byte)(count == 0 ? 0x01 : (!send ? 0x80 : 0)); //处于连续的分片发送
                        contentBytes[1] = 127;
                        byte[] llen = BitConverter.GetBytes((long)sendArr.Length);        //8个字节存储真实长度
                        for (int i = 7; i >= 0; i--)
                        {
                            contentBytes[9 - i] = llen[i];
                        }
                        Array.Copy(sendArr, 0, contentBytes, 10, sendArr.Length);
                    }
                }
                SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs();
                sendArg.SetBuffer(contentBytes, 0, contentBytes.Length);
                socket.SendAsync(sendArg);
                count++;
            }
            return(true);
        }
Exemple #3
0
        /// <summary>
        /// 接受数据
        /// </summary>
        /// <param name="e"></param>
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            if (e.SocketError == SocketError.Success)
            {
                if (e.BytesTransferred > 0)
                {
                    byte[] data = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);//把当前所接收到数据放到data数组里面
                    if (token.SocketConnType == SocketConnType.None)
                    {
                        token.SocketConnType = PacketComm.GetPacketType(data, out string packetStr);
                        if (token.SocketConnType == SocketConnType.WebSocket)                                    //websocket连接
                        {
                            var HandPacket = Comm.BytesToString(PacketComm.AnswerWebSocketHandShake(packetStr)); //应答握手包
                            Send(token, HandPacket);
                        }
                    }
                    else if (token.SocketConnType == SocketConnType.WebSocket)//WebSocket数据包
                    {
                        var Pac_Type = data[0] & 0xF;
                        if (Pac_Type == 8)//WebSocket关闭
                        {
                            CloseClientSocketEx(e, SocketColseType.ClientClose);
                        }
                        else
                        {
                            #region WebSocket数据包 https://www.cnblogs.com/smark/archive/2012/11/26/2789812.html
                            lock (token.Buffer)
                                token.Buffer.AddRange(data);
                            if (token.Socket.Available == 0)//接受完毕
                            {
                                var  buffer = token.Buffer.ToArray();
                                var  len    = buffer.Length;
                                bool mask   = false;
                                int  lodlen = 0;
                                if (len > 2)
                                {
                                    var Pac_Fin = (buffer[0] >> 7) > 0;//是否最后一个数据包
                                    if (Pac_Fin)
                                    {
                                        mask   = (buffer[1] >> 7) > 0;
                                        lodlen = buffer[1] & 0x7F;
                                        byte[] loddata;
                                        byte[] masks = new byte[4];
                                        if (lodlen == 126)
                                        {
                                            Array.Copy(buffer, 4, masks, 0, 4);
                                            lodlen  = (UInt16)(buffer[2] << 8 | buffer[3]);
                                            loddata = new byte[lodlen];
                                            Array.Copy(buffer, 8, loddata, 0, lodlen);
                                        }
                                        else if (lodlen == 127)
                                        {
                                            Array.Copy(buffer, 10, masks, 0, 4);
                                            byte[] uInt64Bytes = new byte[8];
                                            for (int i = 0; i < 8; i++)
                                            {
                                                uInt64Bytes[i] = buffer[9 - i];
                                            }
                                            lodlen = (int)BitConverter.ToUInt64(uInt64Bytes, 0);

                                            loddata = new byte[lodlen];
                                            for (int i = 0; i < lodlen; i++)
                                            {
                                                loddata[i] = buffer[i + 14];
                                            }
                                        }
                                        else
                                        {
                                            Array.Copy(buffer, 2, masks, 0, 4);
                                            loddata = new byte[lodlen];
                                            Array.Copy(buffer, 6, loddata, 0, lodlen);
                                        }
                                        for (var i = 0; i < lodlen; i++)
                                        {
                                            loddata[i] = (byte)(loddata[i] ^ masks[i % 4]);
                                        }
                                        var Message = Comm.BytesToString(loddata);
                                        onReceiveData(token.ConnId, Message, e);
                                    }
                                }
                                lock (token.Buffer)
                                    token.Buffer.Clear();
                            }
                            #endregion
                        }
                    }
                    if (token.SocketConnType == SocketConnType.Socket)//原生Socket数据包
                    {
                        #region 原生Socket数据包
                        lock (token.Buffer)
                            token.Buffer.AddRange(data);
                        do
                        {
                            //**************************包头前8个字节为2个整数,第一个无意义默认为1,第二个为包长******************************************
                            byte[] lenBytes   = token.Buffer.GetRange(4, 4).ToArray();
                            int    packageLen = Comm.BytesToInt32(lenBytes, 0);
                            if (packageLen > token.Buffer.Count - 8)
                            {
                                break;
                            }
                            byte[] rev     = token.Buffer.GetRange(8, packageLen).ToArray();//获取从第8个字节起的净内容(加密过的内容)
                            var    Message = Comm.AESDecrypt(Comm.BytesToString(rev), AESKey);
                            lock (token.Buffer)
                                token.Buffer.RemoveRange(0, packageLen + 8);  //从数据池中移除这组数据
                            onReceiveData(token.ConnId, Message, e);
                        } while (token.Buffer.Count > 8);                     //(前4个字节是gameserverid(int),随后四个字节是内容总长度(int))
                        #endregion
                    }
                    if (token.Socket != null && token.Socket.Connected == true && !token.Socket.ReceiveAsync(e))
                    {
                        ProcessReceive(e);//继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
                    }
                }
                else
                {
                    CloseClientSocketEx(e, SocketColseType.ClientClose);
                }
            }
            else
            {
                CloseClientSocketEx(e, SocketColseType.ClientClose);
            }
        }