Пример #1
0
 public NetPackage(int headerSize, int bufferSize)
 {
     size        = headerSize;           //! size of all data contain header and user data
     _headerSize = headerSize;           //! size of all data contain header and user data
     data        = new byte[bufferSize]; //! it also contains header
     header      = new NetHeader();      //! no allocation needed. It just points to data
 }
Пример #2
0
 /// <summary> Detects acknowledged and lost messages. </summary>
 private void AckDelivered(NetHeader header)
 {
     for (int i = 0; i < sendWindow.Count; i++)
     {
         int seqDist = NetMath.SeqDistance(sendWindow[i], header.AckSequence);
         // This AckSequence is older than the sendWindow's, not useful:
         if (seqDist > 0)
         {
             break;
         }
         // AckHistory has rolled over without acking this message; Ordered reliable is broken:
         if (seqDist <= -64)
         {
             Connection.Disconnect();
         }
         // If the seqDistance corresponds to a true bit in the AckHistory, message delivered/acked:
         else if (IsAcked(header.AckHistory, seqDist))
         {
             MessageDelivered(i, header);
             i--; // Since the sendWindow count will decrease, the index needs to be adjusted.
         }
         // The seqDist is still within the send window, but if too much time has passed, assume lost:
         else if (NetTime.Milliseconds() - sendWindowTime[i] > 333)
         {
             MessageLost(i);
         }
     }
 }
Пример #3
0
 /// <summary> Adds an out-of-order datagram to the buffer to await future delivery. </summary>
 private void BufferOutOfOrder(int seqDist, NetStream strm, NetHeader header)
 {
     if (recvBuffer.Count >= 512)
     {
         Connection.Disconnect();
         return;
     }
     if (recvBufferSeqDist.Contains(seqDist))
     {
         strm.Release();
         return;
     }
     // Ack history window is only 64 bits, so only ack if within window:
     if (seqDist < 64)
     {
         AckReceived(header);
         AckDelivered(header);
     }
     else
     {
         strm.Pos = 1;  // Reset to 1 so header can be reprocessed when seqDist < 64
     }
     recvBuffer.Add(strm);
     recvBufferSeqDist.Add(seqDist);
 }
Пример #4
0
        /// <summary> Handles a stream based on its header/size. Determines if it should be buffered if out-of-order,
        /// acked and released if size is equal to header size (ack only), or delivered immediately. </summary>
        internal void RouteIncomingStream(NetStream strm)
        {
            var header  = NetHeader.FromStream(strm);
            int seqDist = NetMath.SeqDistance(header.ObjSequence, LastAcceptedRemoteSequence);

            // If the stream is only the size of a header, it's likely a forced ack:
            if (strm.Length <= 120)
            {
                AckDelivered(header);
                strm.Release();
            }
            else if (!RemoteSequenceValid(seqDist))
            {
                strm.Release();
            }
            else if (seqDist != 1)
            {
                BufferOutOfOrder(seqDist, strm, header);
            }
            else
            {
                AckReceived(header);
                AckDelivered(header);
                DeliverStream(strm);
            }
        }
Пример #5
0
    public bool VerifyPackage(byte[] buffer, int size, ulong lastNumber)
    {
        //	validate message size
        if (size < NET_HEADER_SIZE || size > NET_BUFF_SIZE)
        {
            return(false);
        }

        NetHeader nh = ByteArrayToNetHeader(buffer);

        //	validate net id
        if (nh.netId != NET_ID)
        {
            return(false);
        }

        //	validate if message is duplicated
        //if ( nh.number == lastNumber && set_hasnt( nh.option, NET_OPTN_SAFESEND ) )
        //    return false;

        //	validate data checksum
        if (size > NET_HEADER_SIZE)
        {
            if (nh.checksum != ComputeChecksum(buffer))
            {
                return(false);
            }
        }

        // new we can suppose that the package is valid
        return(true);
    }
Пример #6
0
 public byte[] NetHeaderToByteArray(NetHeader header)
 {
     byte[] buffer = new byte[NET_HEADER_SIZE];
     Buffer.BlockCopy(BitConverter.GetBytes(header.netId), 0, buffer, 0, 2);
     Buffer.BlockCopy(BitConverter.GetBytes(header.number), 0, buffer, 2, 2);
     Buffer.BlockCopy(BitConverter.GetBytes(header.option), 0, buffer, 4, 2);
     Buffer.BlockCopy(BitConverter.GetBytes(header.checksum), 0, buffer, 6, 2);
     return(buffer);
 }
Пример #7
0
    public NetHeader ByteArrayToNetHeader(byte[] data)
    {
        NetHeader nh = new NetHeader();

        nh.netId    = BitConverter.ToUInt16(data, 0);
        nh.number   = BitConverter.ToUInt16(data, 2);
        nh.option   = BitConverter.ToUInt16(data, 4);
        nh.checksum = BitConverter.ToUInt16(data, 6);
        return(nh);
    }
Пример #8
0
    public void AppendReceivedMessage(NetSocket socket, byte[] buffer, int size)
    {
        outTime     = 0;
        isConnected = true;

        NetHeader nh = NetBase.ByteArrayToNetHeader(buffer);

        //	we are waiting for received confirmation from the other side
        if ((nh.option & NetBase.NET_OPTN_CONFIRMED) > 0)
        {
            if (nh.number == confirmNumber && nh.checksum == confirmChecksum)
            {
                Debug.Log("Info: Message number has been confirmed from other side!");

                confirmNumber = 0;  // confirmed
                retryTime     = 0;

                // remove the message from the sending list
                m_sendingPacks.RemoveAt(0);
            }
            else
            {
                // do nothing !!
            }
        }
        else
        {
            //	replay to sender that safe message has been received
            if ((nh.option & NetBase.NET_OPTN_SAFESEND) > 0)
            {
                NetPacket tmp = new NetPacket();
                tmp.header        = nh;
                tmp.header.option = NetBase.NET_OPTN_CONFIRMED;
                socket.Send(tmp, dest);
            }

            //	create message container and append it to the list
            if (nh.number != recvNumber)
            {
                recvNumber = nh.number;

                NetPacket np = new NetPacket();
                np.header = nh;
                np.data   = new byte[size - NetBase.NET_HEADER_SIZE];

                Buffer.BlockCopy(buffer, NetBase.NET_HEADER_SIZE, np.data, 0, np.data.Length);

                //	add it to the received list
                m_receivedPacks.Add(np);

                //sx_print( L"message received header [NO: %d OP: %d CH: %d]\n", np.header.number, np.header.option, np.header.checksum );
            }
        }
    }
Пример #9
0
 internal static NetHeader Create(NetChannelReliable chan, uint time) {
     var header = new NetHeader {
         AckHistory = chan.AckHistory,
         AckSequence = chan.NewestRemoteSequence,
         ObjSequence = chan.LocalSequence,
         SendTime = time
     };
     if (chan.LastReceiveTime > time) {
         header.AckTime = (ushort)Mathf.Clamp(time - chan.LastReceiveTime, 0, 6000);
     }
     return header;
 }
Пример #10
0
        /// <summary> Removes acked messages from the send window, releases the stream, updates connection ping, and
        /// increments the Delivered stat. </summary>
        private void MessageDelivered(int index, NetHeader header)
        {
            Delivered++;
            NetStream strm = reliableWindow[sendWindow[index]];

            if (header.AckTime > 0)
            {
                Connection.UpdatePing(NetTime.Milliseconds(), sendWindowTime[index], header.AckTime);
            }
            reliableWindow.Remove(sendWindow[index]);
            sendWindow.RemoveAt(index);
            sendWindowTime.RemoveAt(index);
            strm.Release();
        }
Пример #11
0
        /// <summary> Prepares the outgoing reliable stream: Writes the reliable bit & reliable header,
        /// sets stream parameters, and updates send stats. </summary>
        private NetHeader WriteHeader()
        {
            sendStream.Connection = Connection;
            sendStream.Socket     = Connection.Socket;

            sendStream.WriteBool(true);
            var header = NetHeader.Create(this, NetTime.Milliseconds());

            header.ToStream(sendStream);

            ReceivedSinceLastSend = 0;
            Sent++;

            return(header);
        }
Пример #12
0
            internal static NetHeader Create(NetChannelReliable chan, uint time)
            {
                var header = new NetHeader {
                    AckHistory  = chan.AckHistory,
                    AckSequence = chan.NewestRemoteSequence,
                    ObjSequence = chan.LocalSequence,
                    SendTime    = time
                };

                if (chan.LastReceiveTime > time)
                {
                    header.AckTime = (ushort)Mathf.Clamp(time - chan.LastReceiveTime, 0, 6000);
                }
                return(header);
            }
Пример #13
0
        /// <summary> Acknowledges and updates the remote sequence. </summary>
        private void AckReceived(NetHeader header)
        {
            int newestDist = NetMath.SeqDistance(header.ObjSequence, NewestRemoteSequence);

            // If the sequence is newest, shift the buffer and apply ack bit:
            if (newestDist > 0)
            {
                AckHistory           = (AckHistory << newestDist) | 1UL;
                NewestRemoteSequence = header.ObjSequence;
            }
            // Else, shift the ack bit and apply to buffer:
            else
            {
                AckHistory |= 1UL << -newestDist;
            }

            LastReceiveTime = NetTime.Milliseconds();

            ReceivedSinceLastSend++;
            Received++;
        }
Пример #14
0
 /// <summary> Detects acknowledged and lost messages. </summary>
 private void AckDelivered(NetHeader header) {
     for (int i = 0; i < sendWindow.Count; i++) {
         int seqDist = NetMath.SeqDistance(sendWindow[i], header.AckSequence);
         // This AckSequence is older than the sendWindow's, not useful:
         if (seqDist > 0) break;
         // AckHistory has rolled over without acking this message; Ordered reliable is broken:
         if (seqDist <= -64) Connection.Disconnect();
         // If the seqDistance corresponds to a true bit in the AckHistory, message delivered/acked:
         else if (IsAcked(header.AckHistory, seqDist)) {
             MessageDelivered(i, header);
             i--; // Since the sendWindow count will decrease, the index needs to be adjusted.
         }
         // The seqDist is still within the send window, but if too much time has passed, assume lost:
         else if (NetTime.Milliseconds() - sendWindowTime[i] > 333) MessageLost(i);
     }
 }
Пример #15
0
    public void Run()
    {
        RC4Encryption rc4Server = new RC4Encryption();
        RC4Encryption rc4Client = new RC4Encryption();

        rc4Server.makeSBox("zhangyawei");
        rc4Client.makeSBox("zhangyawei");

        IPAddress ip           = IPAddress.Parse("127.0.0.1");
        Socket    clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        try
        {
            clientSocket.Connect(new IPEndPoint(ip, 26001));
            Debug.logger.Log("connect Success.");
        }
        catch
        {
            Debug.logger.Log("connect Failed");
            return;
        }
        if (true)
        {
            ClientAuthReq req     = new ClientAuthReq("test", "123");
            var           binData = req.__encode().ToArray();
            //binData = rc4Client.encryption(binData, binData.Length());

            var sendData = new System.Collections.Generic.List <byte>();

            NetHeader head = new NetHeader();
            head.packLen = (UInt32)(4 + 2 + 2 + binData.Length);
            head.protoID = Proto4z.ClientAuthReq.getProtoID();
            sendData.AddRange(head.__encode());
            sendData.AddRange(binData);
            clientSocket.Send(sendData.ToArray());

            var       recvBytes = new byte[2000];
            uint      curLen    = 0;
            uint      needLen   = 4 + 2 + 2; //暂时分两段读 后面要改buff接收提高效率
            uint      recvLen   = 0;
            NetHeader recvHead  = new NetHeader();
            do
            {
                recvLen = (uint)clientSocket.Receive(recvBytes, (int)curLen, (int)needLen, System.Net.Sockets.SocketFlags.None);//第一段
                if (recvLen == 0)
                {
                    // remote close socket.
                    return;
                }
                curLen  += recvLen;
                needLen -= recvLen;
                if (needLen == 0 && curLen == 4 + 2 + 2) ////第一段 完成
                {
                    int pos = 0;
                    recvHead.__decode(recvBytes, ref pos);
                    needLen = recvHead.packLen - 4 - 2 - 2; //设置第二段
                }
                else if (needLen == 0)                      //第二段完成
                {
                    if (recvHead.protoID == Proto4z.ClientAuthResp.getProtoID())
                    {
                        ClientAuthResp result = new ClientAuthResp();
                        int            pos    = 4 + 2 + 2;
                        result.__decode(recvBytes, ref pos);

                        Debug.logger.Log("ClientAuthResp: account=" + result.account + ", token=" + result.token + ",retCode=" + result.retCode);
                        int t = 0;
                        t++;
                    }
                    else if (true) //other proto
                    {
                    }
                    break; //一个协议接收处理完毕后break
                }
                recvLen = 0;
            } while (true);
        }
    }
Пример #16
0
        public void Run(byte[] binData)
        {
            IPAddress ip           = IPAddress.Parse("127.0.0.1");
            Socket    clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8081)); //zsummerX/example/frameStressTest server default port
                Console.WriteLine("connect Success.");
            }
            catch
            {
                Console.WriteLine("connect Failed");
                return;
            }
            do
            {
                var sendData = new System.Collections.Generic.List <byte>();

                NetHeader head = new NetHeader();
                head.packLen = (UInt32)(4 + 2 + 2 + binData.Length);
                head.protoID = Proto4z.EchoPack.getProtoID();

                sendData.AddRange(head.__encode());
                sendData.AddRange(binData);
                clientSocket.Send(sendData.ToArray());



                var       recvBytes = new byte[2000];
                uint      curLen    = 0;
                uint      needLen   = 4 + 2 + 2;
                uint      recvLen   = 0;
                NetHeader recvHead  = new NetHeader();
                do
                {
                    recvLen = (uint)clientSocket.Receive(recvBytes, (int)curLen, (int)needLen, System.Net.Sockets.SocketFlags.None);
                    if (recvLen == 0)
                    {
                        return;
                    }
                    curLen  += recvLen;
                    needLen -= recvLen;
                    if (needLen == 0 && curLen == 4 + 2 + 2) //head already read finish
                    {
                        int pos = 0;
                        recvHead.__decode(recvBytes, ref pos);
                        needLen = recvHead.packLen - 4 - 2 - 2;
                    }
                    else if (needLen == 0)
                    {
                        if (recvHead.protoID == Proto4z.EchoPack.getProtoID())
                        {
                            Proto4z.EchoPack result = new Proto4z.EchoPack();
                            int pos = 4 + 2 + 2;
                            result.__decode(recvBytes, ref pos);
                            //System.Console.WriteLine("echo =" + result.text.val);
                        }
                        break;
                    }
                    recvLen = 0;
                } while (true);
            } while (true);
        }
Пример #17
0
    public void AppendReceivedMessage(byte[] buffer, int size)
    {
        outTime     = 0;
        isConnected = true;

        byte[] headerBuffer = new byte[net.NET_HEADER_SIZE];

        Buffer.BlockCopy(buffer, 0, headerBuffer, 0, net.NET_HEADER_SIZE);

        NetHeader nh = net.ByteArrayToNetHeader(buffer);

        //	we are waiting for received confirmation from the other side
        if ((nh.option & net.NET_OPTN_CONFIRMED) > 0)
        {
            if (nh.number == confirmNumber && nh.checksum == confirmChecksum)
            {
                //sx_print(L"Info: Message number %d has been confirmed from other side!\n", confirmNumber);

                confirmNumber = 0;  // confirmed
                retryTime     = 0;

                // remove the message from the sending list
                m_sendingPacks.RemoveAt(0);
            }
            else
            {
                // do nothing !!
            }
        }
        else
        {
            //	replay to sender that safe message has been received
            if ((nh.option & net.NET_OPTN_SAFESEND) > 0)
            {
                NetPackage tmp = new NetPackage(net.NET_HEADER_SIZE, net.NET_BUFF_SIZE);
                tmp.header        = nh;
                tmp.header.option = net.NET_OPTN_CONFIRMED;
                byte[] tmpBuf = net.NetHeaderToByteArray(tmp.header);
                Buffer.BlockCopy(tmpBuf, 0, tmp.data, 0, net.NET_HEADER_SIZE);
                net.socket.Send(dest, tmp.data, tmp.size);
            }

            //	create message container and append it to the list
            if (nh.number != recvNumber)
            {
                recvNumber = nh.number;

                NetPackage np = new NetPackage(net.NET_HEADER_SIZE, net.NET_BUFF_SIZE);
                np.size = size;

                np.header = nh;

                Buffer.BlockCopy(buffer, 0, np.data, 0, size);

                //	add it to the received list
                m_receivedPacks.Add(np);

                //sx_print( L"message received header [NO: %d OP: %d CH: %d]\n", np.header.number, np.header.option, np.header.checksum );
            }
        }
    }
Пример #18
0
        public void Run(byte[] binData)
        {

            IPAddress ip = IPAddress.Parse("127.0.0.1");
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8081)); //zsummerX/example/frameStressTest server default port 
                Console.WriteLine("connect Success.");
            }
            catch
            {
                Console.WriteLine("connect Failed");
                return;
            }
            do
            {
                var sendData = new System.Collections.Generic.List<byte>();

                NetHeader head = new NetHeader();
                head.packLen = (UInt32)(4 + 2 + 2 + binData.Length);
                head.protoID = Proto4z.EchoPack.getProtoID();

                sendData.AddRange(head.__encode());
                sendData.AddRange(binData);
                clientSocket.Send(sendData.ToArray());


                
                
                var recvBytes = new byte[2000];
                uint curLen = 0;
                uint needLen = 4 + 2 + 2;
                uint recvLen = 0;
                NetHeader recvHead = new NetHeader();
                do
                {
                    recvLen = (uint)clientSocket.Receive(recvBytes, (int)curLen, (int)needLen, System.Net.Sockets.SocketFlags.None);
                    if (recvLen == 0)
                    {
                        return;
                    }
                    curLen += recvLen;
                    needLen -= recvLen;
                    if (needLen == 0 && curLen == 4 + 2 + 2) //head already read finish
                    {
                        int pos = 0;
                        recvHead.__decode(recvBytes, ref pos);
                        needLen = recvHead.packLen - 4 - 2 - 2;
                    }
                    else if (needLen == 0)
                    {
                        if (recvHead.protoID == Proto4z.EchoPack.getProtoID())
                        {
                            Proto4z.EchoPack result = new Proto4z.EchoPack();
                            int pos = 4+2+2;
                            result.__decode(recvBytes, ref pos);
                            //System.Console.WriteLine("echo =" + result.text.val);
                        }
                        break;
                    }
                    recvLen = 0;
                } while (true);


            } while (true);

        }
Пример #19
0
        /// <summary> Adds an out-of-order datagram to the buffer to await future delivery. </summary>
        private void BufferOutOfOrder(int seqDist, NetStream strm, NetHeader header) {
            if (recvBuffer.Count >= 512) {
                Connection.Disconnect();
                return;
            }
            if (recvBufferSeqDist.Contains(seqDist)) {
                strm.Release();
                return;
            }
            // Ack history window is only 64 bits, so only ack if within window:
            if (seqDist < 64) {
                AckReceived(header);
                AckDelivered(header);
            }
            else strm.Pos = 1; // Reset to 1 so header can be reprocessed when seqDist < 64

            recvBuffer.Add(strm);
            recvBufferSeqDist.Add(seqDist);
        }
Пример #20
0
        /// <summary> Acknowledges and updates the remote sequence. </summary>
        private void AckReceived(NetHeader header) {
            int newestDist = NetMath.SeqDistance(header.ObjSequence, NewestRemoteSequence);
            // If the sequence is newest, shift the buffer and apply ack bit:
            if (newestDist > 0) {
                AckHistory = (AckHistory << newestDist) | 1UL;
                NewestRemoteSequence = header.ObjSequence;
            }
            // Else, shift the ack bit and apply to buffer:
            else AckHistory |= 1UL << -newestDist;

            LastReceiveTime = NetTime.Milliseconds();

            ReceivedSinceLastSend++;
            Received++;
        }
Пример #21
0
 /// <summary> Removes acked messages from the send window, releases the stream, updates connection ping, and 
 /// increments the Delivered stat. </summary>
 private void MessageDelivered(int index, NetHeader header) {
     Delivered++;
     NetStream strm = reliableWindow[sendWindow[index]];
     if (header.AckTime > 0) Connection.UpdatePing(NetTime.Milliseconds(), sendWindowTime[index], header.AckTime);
     reliableWindow.Remove(sendWindow[index]);
     sendWindow.RemoveAt(index);
     sendWindowTime.RemoveAt(index);
     strm.Release();
 }