public void WaitForSynAck()
        {
            EndPoint sender = (EndPoint)_endPoint;
            var      ackn   = new byte[RPH.GetPacketByteLength()];

            // set the timeout for receiving acks (retransmission timeout)
            _sendingSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, Timeout);
            try
            {
                _sendingSocket.ReceiveFrom(ackn, ref sender);

                var rph = RPH.Deserialize(ackn);
                if (IsCorrupt(rph) || !IsSynAck(rph))
                {
                    _currentState = State.EstablishConnection;
                    return;
                }
                else
                {
                    Console.WriteLine("Connection Established");
                    _currentState = State.SendPacket;
                }
            }
            catch (SocketException e)
            {
                if (e.SocketErrorCode == SocketError.TimedOut)
                {
                    Console.WriteLine(e.ToString());
                    Console.WriteLine("No Connection could be established");
                }
                _currentState = State.EstablishConnection;
            }
        }
        private void WaitForAck()
        {
            EndPoint sender = (EndPoint)_endPoint;
            var      ackn   = new byte[RPH.GetPacketByteLength()];

            _tries++;

            if (MaxRetransTries < _tries)
            {
                _currentState = State.FatalError;
                return;
            }

            try
            {
                _sendingSocket.ReceiveFrom(ackn, ref sender);

                var rph = RPH.Deserialize(ackn);

                // Ack is corrupt
                if (IsCorrupt(rph, ackn) || !IsAck(rph))
                {
                    // If Ack is corrupt resend Packet
                    Console.WriteLine("Corrupt or NAck: Resend Packet");
                }
                else if (IsAck(rph) && !IsCorrupt(rph) && rph._ackNr != _localSeqNr)
                {
                    _tries = 0;
                    Debug.Assert(rph != null, "rph != null");
                    _localSeqNr  += _filechunk.Length;
                    _currentState = State.SendPacket;
                }
                else
                {
                    Console.WriteLine("Not defined");
                }
            }
            catch (SocketException e)
            {
                if (e.SocketErrorCode == SocketError.TimedOut)
                {
                    // Timeout: Resend Packet
                    Console.WriteLine("Timeout: Resend Packet");
                    SendOnePacket();
                }
                else
                {
                    Console.WriteLine("Fatal Error");
                    _currentState = State.FatalError;
                    return;
                }
            }
        }
        private void SendOnePacket()
        {
            int headSize = RPH.GetPacketByteLength();

            byte[] packetBuf = null;

            if (!IsLastPacket(PacketSizeBytes - headSize))
            {
                _filechunk = FileToChunk(_fileData, _localSeqNr, PacketSizeBytes - headSize);
                packetBuf  = new byte[PacketSizeBytes];
            }
            else
            {
                _filechunk = FileToChunk(_fileData, _localSeqNr, _fileData.Length - _localSeqNr);
                packetBuf  = new byte[_filechunk.Length + headSize];
                _fileSend  = true;
            }

            var rph = RPH.CreatePacketHeader(_localSeqNr, 0);

            byte[] header = rph.Serialize();

            // Copy together one packet: header with payload
            Array.Copy(header, packetBuf, headSize);
            Array.Copy(_filechunk, 0, packetBuf, headSize, _filechunk.Length);

            // Last set the Checksum of the packet
            SetChecksum(ref packetBuf);

            // Now Send the packet
            _sendingSocket.SendTo(packetBuf, _endPoint);

            Console.WriteLine("Paket versendet");

            // Change State
            _currentState = State.WaitForAck;
        }