@Override public void run() { while (!close.get()) { byte[] buffer = new byte[Pacote.default_size]; DatagramPacket packet = new DatagramPacket(buffer, Pacote.default_size); try { real_socket.receive(packet); // recebe um pacote int key = OperacoesBinarias.extrairNumeroReconhecimento(buffer); int seqNum = OperacoesBinarias.extrairNumeroSequencia(buffer); int dataLength = OperacoesBinarias.extrairComprimentoDados(buffer); if (OperacoesBinarias.extrairFIN(buffer)) { if (arquivo_enviar != null) { arquivo_enviar.close(); } if (arquivo_receber != null) { arquivo_receber.close(); } close.set(true); miniSocket.this.close(); } else if (OperacoesBinarias.extrairSYN(buffer)) { } else if (OperacoesBinarias.extrairACK(buffer)) { if (packet.getAddress().equals(client_adress) && packet.getPort() == client_port) { // tenho um ack de quem me comunico Pacote temp = null; synchronized (sinc_send_buffer) { int remap = key - send_packets_cont.get(); if ((remap) < send_packet_buffer.size() && !send_packet_buffer.isEmpty() && remap >= 0) { // verifica se o pacote esta dentro das possibilidades do buffer temp = send_packet_buffer.get(remap); temp_SampleRTT.set( System.currentTimeMillis() - temp.send_time); // atualiza variavel com sampleRTT temporário if (!temp.isEnviado()) { temp.setEnviado(true); cwin.set(Math.min(cwin.get() + 10, max_win)); } } } if (key > estimateRTT_for_packet.get() && estimateRTT_process.get() && temp != null) { long temp_SampleRTT = System.currentTimeMillis() - temp.send_time; // Calculo sampleRTT EstimatedRTT = (long) ((EstimatedRTT * 0.875) + (0.125 * temp_SampleRTT)); // Use para Estimar o proximoRTT DevRTT = (long) ((0.75 * DevRTT) + (0.25 * Math.abs(temp_SampleRTT - EstimatedRTT))); // E também o DevRTT timeout.set(EstimatedRTT + (4 * DevRTT)); // E altere o timeout estimateRTT_process.set(false); } } else { System.out.println( "Recebi um ACK de um host estranho. Cuidado a rede pode estar sendo invadida!"); } } else if (OperacoesBinarias.extrairRST(buffer)) { arquivo_receber.close(); } else { // temos um pacote com dados if (packet.getAddress().equals(server_adress) && packet.getPort() == server_port) { // tenho um ack de quem me comunico byte[] to_ack = new byte[Pacote.head_payload]; OperacoesBinarias.inserirCabecalho( to_ack, 0, seqNum, true, false, false, false, 0, rcv_base.get() + rwin.get()); DatagramPacket ack = new DatagramPacket(to_ack, Pacote.head_payload, server_adress, server_port); synchronized (sinc_send_socket) { // envia ack real_socket.send(ack); } if (seqNum == rcv_base.get()) { // se temos o proximo pacote esperado arquivo_receber.write( buffer, Pacote.head_payload, dataLength); // escreve para camada de cima rcv_base.incrementAndGet(); // incrementa a base da janela // velocidade.getAndAdd(dataLength); last_receiverd += dataLength; // tenta pegar mais pacotes que possa estar no buffer de recepção while (rec_packet_buffer.get(rcv_base.get()) != null) { byte[] dados = rec_packet_buffer.get(rcv_base.get()); dataLength = OperacoesBinarias.extrairComprimentoDados(dados); // velocidade.getAndAdd(dataLength); last_receiverd += dataLength; rcv_base.incrementAndGet(); // incrementa a base de recepção para o proximo pacote arquivo_receber.write(dados, Pacote.head_payload, dataLength); } } else if (seqNum > rcv_base.get()) { // se não temos o proximo pacote esperado // coloca ele no buffer rec_packet_buffer.put(seqNum, buffer); } else { System.out.println("Retransmissao"); } } } } catch (IOException e) { System.out.println("Deu merda no Socket do receiver fechando conexão..."); close.set(true); } } System.out.println("Receiver Encerrado..."); }