예제 #1
0
        private async Task RecievePacket(UdpReceiveResult packet)
        {
            long startAbsolutePosition;

            switch ((CommandCode)packet.Buffer[0])
            {
            case CommandCode.ConnectAck:
                lock (this)
                {
                    state = ClientSocketState.Working;
                    Monitor.Pulse(this);
                }

                LastRecieved = DateTime.Now;
                Console.WriteLine($"Connect acked");

                break;

            case CommandCode.Data:
                Console.WriteLine($"Incoming data");
                startAbsolutePosition = BitConverter.ToInt64(packet.Buffer, 1);

                LastRecieved = DateTime.Now;

                bool added;
                lock (RecieveBuffer)
                {
                    try
                    {
                        added = RecieveBuffer.TryAdd(packet.Buffer, 9, packet.Buffer.Length - 9,
                                                     startAbsolutePosition);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        break;
                    }
                    Monitor.PulseAll(RecieveBuffer);
                }

                Console.WriteLine($"Data got, added:{added}");

                if (added)
                {
                    byte[] message = new byte[1 + 8 + 8];
                    message[0] = (byte)CommandCode.DataAck;
                    Array.Copy(packet.Buffer, 1, message, 1, 8);

                    byte[] length = BitConverter.GetBytes((long)(packet.Buffer.Length - 9));
                    Array.Copy(length, 0, message, 1 + 8, 8);

                    await udpclient.SendAsync(message, message.Length, packet.RemoteEndPoint);
                }
                else
                {
                    byte[] message = { (byte)CommandCode.Overloaded };
                    await udpclient.SendAsync(message, message.Length, packet.RemoteEndPoint);
                }

                break;

            case CommandCode.DataAck:
                startAbsolutePosition = BitConverter.ToInt64(packet.Buffer, 1);
                long dataBytesCount = BitConverter.ToInt64(packet.Buffer, 1 + 8);

                LastRecieved       = DateTime.Now;
                LastSend           = DateTime.Now + overloadedPause; // For next data to be sent w/o timeout
                failedSendAttempts = 0;

                Console.WriteLine($"Data ack got pos: {startAbsolutePosition} count: {dataBytesCount}");

                lock (SendBuffer)
                {
                    SendBuffer.DisposeElements(startAbsolutePosition, (int)dataBytesCount);
                    Monitor.PulseAll(SendBuffer);
                }

                break;

            case CommandCode.Overloaded:
                LastRecieved       = DateTime.Now;
                LastSend           = DateTime.Now + overloadedPause; // For next data to be sent after pause
                failedSendAttempts = 0;

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }