internal TCPSegment GetTCPSyncSegment()
 {
     SeqNumber = (uint)R.Next();
     _initSeqNumber = SeqNumber;
     // 1st step handshake
     TCPSegment tcpSyncSegment = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
     tcpSyncSegment.SYN_Flag = true;
     tcpSyncSegment.SEQ_Number = SeqNumber;
     return tcpSyncSegment;
 }
        internal List<TCPSegment> ProcesarSegmento(TCPSegment segmentoOrigen)
        {
            List<TCPSegment> segmentos = new List<TCPSegment>();
            /// 2ns setp hand shacke
            if (segmentoOrigen.SYN_Flag &&
                !segmentoOrigen.ACK_Flag &&
                segmentoOrigen.DataLength == 0)
            {
                SeqNumber = (uint)R.Next();
                ACKNumber = segmentoOrigen.SEQ_Number + 1;

                TCPSegment segmentoRetorno = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
                segmentoRetorno.SYN_Flag = true;
                segmentoRetorno.ACK_Flag = true;
                segmentoRetorno.SEQ_Number = SeqNumber;
                segmentoRetorno.ACK_Number = ACKNumber;
                segmentos.Add(segmentoRetorno);
                return segmentos;
            }
            // 3rd step hand shake server
            if (segmentoOrigen.ACK_Flag &&
                !segmentoOrigen.FinFlag &&
                !segmentoOrigen.SYN_Flag &&
                segmentoOrigen.ACK_Number == SeqNumber + 1 &&
                !_fin &&
                (segmentoOrigen.DataLength == 0))
            {
                SeqNumber = segmentoOrigen.ACK_Number;
                SegmentSize = segmentoOrigen.SegmentSize;
                return segmentos;
            }
            /// Transferencia
            if (segmentoOrigen.ACK_Flag &&
                !segmentoOrigen.FinFlag &&
                segmentoOrigen.ACK_Number == SeqNumber &&
                segmentoOrigen.SEQ_Number == ACKNumber&&
                (segmentoOrigen.DataLength != 0))
            {
                SegmentSize = segmentoOrigen.DataLength;
                ACKNumber = segmentoOrigen.SEQ_Number + (uint)SegmentSize + 1;
                TCPSegment segmentoRetorno = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
                segmentoRetorno.ACK_Flag = true;
                segmentoRetorno.SEQ_Number = SeqNumber;
                segmentoRetorno.ACK_Number = ACKNumber;
                segmentos.Add(segmentoRetorno);
                return segmentos;


            }
            
            /// Fin ACK
            if (segmentoOrigen.ACK_Flag &&
                segmentoOrigen.FinFlag &&
                segmentoOrigen.ACK_Number == SeqNumber &&
                segmentoOrigen.SEQ_Number == ACKNumber + segmentoOrigen.DataLength &&
                (segmentoOrigen.DataLength == 0))
            {
                ACKNumber = segmentoOrigen.SEQ_Number + 1;
                SeqNumber = segmentoOrigen.ACK_Number;

                TCPSegment segmentoACK_FIN = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
                segmentoACK_FIN.ACK_Flag = true;
                segmentoACK_FIN.SEQ_Number = SeqNumber;
                segmentoACK_FIN.ACK_Number = ACKNumber;
                segmentos.Add(segmentoACK_FIN);

                TCPSegment segmentoFIN = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
                segmentoFIN.ACK_Flag = true;
                segmentoFIN.FinFlag = true;
                segmentoFIN.SEQ_Number = SeqNumber;
                segmentoFIN.ACK_Number = ACKNumber;
                segmentos.Add(segmentoFIN);
                _fin = true;
                return segmentos;

            }
            if (segmentoOrigen.ACK_Flag &&
                !segmentoOrigen.FinFlag &&
                segmentoOrigen.ACK_Number == SeqNumber +1&&
                segmentoOrigen.SEQ_Number == ACKNumber &&
                _fin &&
                (segmentoOrigen.DataLength == 0))
            {
                Data = segmentoOrigen.Data;
                FileName = segmentoOrigen.FileName;
                if (ArchivoRecibido != null)
                {
                    ArchivoRecibido(this, new EventArgs());
                }
                

            }
            return segmentos;
        }
        public List<TCPSegment> ProcesarSegmento(TCPSegment segmentoOrigen)
        {
            List<TCPSegment> segmentos = new List<TCPSegment>();
            // 3rd setp handshake
            if (segmentoOrigen.SYN_Flag &&
                segmentoOrigen.ACK_Flag &&
                !segmentoOrigen.FinFlag &&
                segmentoOrigen.DataLength == 0 &&
                SeqNumber - _initSeqNumber != Data.Length &&
                segmentoOrigen.ACK_Number == SeqNumber + 1)
            {
                ACKNumber = segmentoOrigen.SEQ_Number + 1;
                SeqNumber = segmentoOrigen.ACK_Number;

                TCPSegment segmentoRetorno = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
                segmentoRetorno.ACK_Flag = true;
                segmentoRetorno.SEQ_Number = SeqNumber;
                segmentoRetorno.ACK_Number = ACKNumber;
                segmentoRetorno.SegmentSize = SegmentSize;
                segmentos.Add(segmentoRetorno);
                TCPSegment segmentoprimerDato = new TCPSegment(PuertoOrigen, PuertoDestino, null, SegmentSize);
                segmentoprimerDato.ACK_Flag = true;
                segmentoprimerDato.SEQ_Number = SeqNumber;
                segmentoprimerDato.ACK_Number = ACKNumber;
                segmentos.Add(segmentoprimerDato);
                return segmentos;
            }

            if (!segmentoOrigen.SYN_Flag &&
                 segmentoOrigen.ACK_Flag &&
                 segmentoOrigen.FinFlag &&
                segmentoOrigen.DataLength == 0 &&
              SeqNumber - _initSeqNumber -2== Data.Length &&
              segmentoOrigen.ACK_Number == SeqNumber + 1)
            {
                ACKNumber = segmentoOrigen.SEQ_Number + 1;
                SeqNumber = segmentoOrigen.ACK_Number;

                TCPSegment segmentoRetorno = new TCPSegment(PuertoOrigen, PuertoDestino, Data, 0);
                segmentoRetorno.FileName = FileName;
                segmentoRetorno.ACK_Flag = true;
                segmentoRetorno.SEQ_Number = SeqNumber;
                segmentoRetorno.ACK_Number = ACKNumber;
                segmentos.Add(segmentoRetorno);
                if (FinComunicacion != null)
                    FinComunicacion(this, new EventArgs());
                Console.WriteLine("fin host");
                return segmentos;
            }

            // Data Transfer
            if (!segmentoOrigen.SYN_Flag &&
                segmentoOrigen.ACK_Flag &&
                !segmentoOrigen.FinFlag &&
                segmentoOrigen.ACK_Number == SeqNumber + SegmentSize + 1 &&
                SeqNumber - _initSeqNumber != Data.Length &&
                segmentoOrigen.DataLength == 0)
            {
                SeqNumber = segmentoOrigen.ACK_Number;
                int bytesTransmited = (int)SeqNumber - (int)_initSeqNumber - 1;
                if (bytesTransmited >= Data.Length)
                {
                    segmentos.Add(GetFinRequest());
                    return segmentos;
                }
                TCPSegment segmentoRetorno = new TCPSegment(PuertoOrigen, PuertoDestino, null, SegmentSize);
                segmentoRetorno.ACK_Flag = true;
                segmentoRetorno.SEQ_Number = SeqNumber;
                segmentoRetorno.ACK_Number = ACKNumber;
                int segmentSize = SegmentSize;
                if (Data.Length - bytesTransmited < SegmentSize)
                {
                    segmentSize = Data.Length - bytesTransmited;
                    segmentoRetorno.Data = Data;
                }
                SegmentSize = segmentSize;
                segmentoRetorno.DataLength = SegmentSize;
                segmentos.Add(segmentoRetorno);

                return segmentos;
            }
            return segmentos;
        }
 internal TCPSegment GetPrimerSegmentoStream()
 {
     TCPSegment segmento = new TCPSegment(PuertoOrigen, PuertoDestino, null, SegmentSize);
     segmento.ACK_Flag = true;
     segmento.SEQ_Number = SeqNumber;
     segmento.ACK_Number = ACKNumber;
     segmento.DataLength = SegmentSize;
     return segmento;
 }
 private TCPSegment GetFinRequest()
 {
     TCPSegment tcpFInSegment = new TCPSegment(PuertoOrigen, PuertoDestino, null, 0);
     tcpFInSegment.FinFlag = true;
     tcpFInSegment.ACK_Flag = true;
     SeqNumber = SeqNumber;
     tcpFInSegment.SEQ_Number = SeqNumber;
     tcpFInSegment.ACK_Number = ACKNumber;
     return tcpFInSegment;
 }