Skip to content

Commit

Permalink
WIP - passo 6
Browse files Browse the repository at this point in the history
  • Loading branch information
YaboiAst committed Sep 1, 2023
1 parent 5cf3868 commit 1344160
Showing 1 changed file with 51 additions and 13 deletions.
64 changes: 51 additions & 13 deletions tcp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import asyncio
from os import truncate
import random
import sys
import time
from grader.tcputils import *

class Servidor:
Expand Down Expand Up @@ -47,6 +49,7 @@ def _rdt_rcv(self, src_addr, dst_addr, segment):
if (flags & FLAGS_SYN) == FLAGS_SYN:
# A flag SYN estar setada significa que é um cliente tentando estabelecer uma conexão nova
# TODO: talvez você precise passar mais coisas para o construtor de conexão
print("Conexão aceita")
conexao = self.conexoes[id_conexao] = Conexao(self, id_conexao, seq_no)
ack_no = seq_no + 1
response = fix_checksum(
Expand All @@ -67,49 +70,59 @@ def _rdt_rcv(self, src_addr, dst_addr, segment):
(src_addr, src_port, dst_addr, dst_port))


#self.timer = asyncio.get_event_loop().call_later(1, self._exemplo_timer) # um timer pode ser criado assim; esta linha é só um exemplo e pode ser removida
#self.timer.cancel() # é possível cancelar o timer chamando esse método; esta linha é só um exemplo e pode ser removida

class Conexao:
def __init__(self, servidor, id_conexao, seq_no):
self.servidor = servidor
self.id_conexao = id_conexao
self.callback = None

self.seq_no = seq_no
self.expected_seq = seq_no + 1
self.ack_no = seq_no + 1

self.current_segment = None
self.not_yet_acked = b''

self.timer = None
self.is_timer_up = False

self.time0 = time.time()
self.time1 = 0.0
self.sampleRTT = 0.0
self.estimatedRTT = 0.0
self.devRTT = 0.0
self.timeoutInterval = 0.5
self.is_retransmitted = True

def reenviar_pacote(self):
self.timer.cancel()
self.is_timer_up = False

self.is_retransmitted = True

src_addr, src_port, dst_addr, dst_port = self.id_conexao
header = fix_checksum(make_header(dst_port, src_port, self.seq_no, self.ack_no, FLAGS_ACK), dst_addr, src_addr)

segment = self.not_yet_acked[:MSS]
self.servidor.rede.enviar(header + segment, src_addr)

self.timer = asyncio.get_event_loop().call_later(0.5, self.reenviar_pacote)
print("Reenviando pacote em ", self.timeoutInterval)
self.timer = asyncio.get_event_loop().call_later(self.timeoutInterval, self.reenviar_pacote)
self.is_timer_up = True
#timer = asyncio.get_event_loop().call_later(1, self.reenviar_pacote)

def _rdt_rcv(self, seq_no, ack_no, flags, payload):
# TODO: trate aqui o recebimento de segmentos provenientes da camada de rede.
# Chame self.callback(self, dados) para passar dados para a camada de aplicação após
# garantir que eles não sejam duplicados e que tenham sido recebidos em ordem.

src_addr, src_port, dst_addr, dst_port = self.id_conexao
self.time1 = time.time()

if(self.ack_no != seq_no):
if (self.ack_no != seq_no):
return

print('recebido payload: %r' % payload)

if (flags & FLAGS_SYN) == FLAGS_SYN:
print("Conexão aceita")
return

if (flags & FLAGS_FIN) == FLAGS_FIN:
self.ack_no += 1
Expand All @@ -120,25 +133,46 @@ def _rdt_rcv(self, seq_no, ack_no, flags, payload):

self.ack_no += len(payload)

if(len(payload) > 0):
if (len(payload) > 0):
print('recebido payload: %s' % payload)
segment = fix_checksum(make_header(dst_port, src_port, self.seq_no, self.ack_no, FLAGS_ACK), dst_addr, src_addr)
self.callback(self, payload)
self.servidor.rede.enviar(segment, src_addr)
return

if (flags & FLAGS_ACK) == FLAGS_ACK:
print("recebeu uma resposta ACK")
print("\nrecebeu uma resposta ACK")
if(self.is_timer_up == True):
self.timer.cancel()
self.timer = None
self.is_timer_up = False

if(self.is_retransmitted == False):
print(self.time0)
print(self.time1)
self.sampleRTT = (self.time1 - self.time0)
print("sample RTT: ", self.sampleRTT)

self.devRTT = ((0.75) * self.devRTT) + ((0.25) * abs(self.sampleRTT - self.estimatedRTT))
self.estimatedRTT = ((0.875) * self.estimatedRTT) + ((0.125) * self.sampleRTT)

if (self.estimatedRTT == 0.125 * self.sampleRTT):
print("calculando rtt pela primeira vez")
self.devRTT = self.sampleRTT / 2
self.estimatedRTT = self.sampleRTT

print("estimated RTT: ", self.estimatedRTT)
print("dev RTT: ", self.devRTT)

self.timeoutInterval = round((self.estimatedRTT + 4 * (self.devRTT)), 2)
print("Timeout Interval: ", self.timeoutInterval)

self.not_yet_acked = self.not_yet_acked[ack_no - self.seq_no:]
self.seq_no = ack_no

if ack_no < self.expected_seq:
self.is_timer_up = True
self.timer = asyncio.get_event_loop().call_later(0.5, self.reenviar_pacote)
self.timer = asyncio.get_event_loop().call_later(self.timeoutInterval, self.reenviar_pacote)

# Os métodos abaixo fazem parte da API

Expand All @@ -156,15 +190,19 @@ def enviar(self, dados):
# TODO: implemente aqui o envio de dados.
# Chame self.servidor.rede.enviar(segmento, dest_addr) para enviar o segmento
# que você construir para a camada de rede.
self.is_retransmitted = False

src_addr, src_port, dst_addr, dst_port = self.id_conexao
segment = [dados[i: i + MSS] for i in range(0, len(dados), MSS)]
for seg in segment:
self.current_segment = fix_checksum(make_header(dst_port, src_port, self.expected_seq, self.ack_no, FLAGS_ACK) + seg, dst_addr, src_addr)
self.servidor.rede.enviar(self.current_segment, dst_addr)
self.time0 = time.time()
self.expected_seq += len(seg)

self.not_yet_acked += seg
self.timer = asyncio.get_event_loop().call_later(0.5, self.reenviar_pacote)
print("Reenviando pacote em ", self.timeoutInterval)
self.timer = asyncio.get_event_loop().call_later(self.timeoutInterval, self.reenviar_pacote)

pass

Expand Down

0 comments on commit 1344160

Please sign in to comment.