Exemple #1
0
    def abrir_conexao(self, ip, porta):
        tupla_conn = (ip, porta)
        pacote = Pacote()
        pacote.set([['porta_dest', porta], ['syn', 1], ['seq', self.seq],
                    ['RTT', time.time()]])
        raw_pacote = json.dumps(pacote.conteudo)
        print("Tentando se conectar a %s:%d." % (ip, porta))
        # Enviando requisição SYN
        self.sock.sendto(raw_pacote, tupla_conn)
        self.sock.settimeout(5.0)
        # Caso o pacote se perca o client tenta reenviar a requisição
        while True:
            try:
                raw_pacote, conn = self.sock.recvfrom(self.MTU)
                break
            except:
                self.sock.sendto(raw_pacote, tupla_conn)
                print("Não houve resposta do servidor, tentando novamente.")

        print("Pacote de resposta recebido.")
        pacote.conteudo = json.loads(raw_pacote)
        if pacote.conteudo['flags']['syn'] and pacote.conteudo['flags']['ack']:
            print("O servidor enviou SYN ACK. Enviando ACK.")
            self.timeout = min(8, pacote.conteudo['RTT'])
            self.sock.settimeout(self.timeout)
            # Caso haja resposta o RTT é calculado e além disso uma resposta é gerada e enviada
            self.ack = pacote.conteudo['seq'] + 1
            pacote.set([['porta_orig', pacote.conteudo['porta_dest']],
                        ['porta_dest', porta], ['syn', 0], ['seq', self.seq],
                        ['ack_n', self.ack], ['RTT', time.time()]])
            raw_pacote = json.dumps(pacote.conteudo)
            self.sock.sendto(raw_pacote, tupla_conn)
            print("Conexão Estabelecida.")

            # O socket e as informações de conexão são retornadas para o client
            return self.sock, tupla_conn
        else:
            # Caso o servidor rejeite a conexão há uma opção de tentar novamente ou abandonar a conexão
            print("O servidor não quis estabelecer conexão.")
            print("Tentar novamente? [S/n]")
            if input().lower() == "n":
                print("Adeus.")
                return False
            else:
                print("Tentando novamente...")
                self.abrir_conexao(ip, porta)
Exemple #2
0
    def enviar_dados(self, dados, sock, ip, porta):
        self.sock = sock
        tupla_conn = (ip, porta)
        pacote = Pacote()

        # Caso os dados sejam maiores que o MSS o pacote será segmentado
        if (len(dados) >= self.MSS):
            print("O pacote é muito grande e será (provavelmente) dividido em",
                  len(dados) // self.MSS + 1, "segmentos.")
            self.cria_segmentos(dados, porta)
        else:
            self.multiplexacao(dados, porta)

        if not self.buffer:
            print("O buffer está vazio.")
        else:
            # Loop de envio e recebimento dos dados
            while self.indiceBuffer < len(self.buffer):
                cont = 0
                if self.cwnd * self.MSS > self.ssthresh:
                    self.exponencial = False

                pacotes_enviados = 0
                # Loop de envio do que está no buffer de acordo com o cwnd
                while cont < self.cwnd:
                    if self.indiceBuffer >= len(self.buffer):
                        pacotes_enviados = cont
                        break
                    raw_pacote = json.dumps(self.buffer[self.indiceBuffer])
                    self.sock.sendto(raw_pacote, tupla_conn)
                    self.indiceBuffer += 1
                    cont += 1
                    pacotes_enviados += 1

                print(cont, "segmentos enviados.")

                cont = 0
                # Loop de recebimento dos dados
                while cont < pacotes_enviados:
                    while True:
                        try:
                            raw_pacote, conn = self.sock.recvfrom(self.MTU)
                            break
                        except:
                            print("Timeout, iniciando a partida lenta")
                            self.ssthresh = self.cwnd * self.MSS / 2
                            self.exponencial = True
                            self.cwnd = 1
                            self.sock.sendto(raw_pacote, tupla_conn)

                    pacote.conteudo = json.loads(raw_pacote)

                    if self.ack - 1 == pacote.conteudo['seq']:
                        if self.seq == pacote.conteudo['ack_n'] - 1:
                            self.ack += len(pacote.conteudo['dados'])
                            self.timeout = min(8, pacote.conteudo['RTT'])
                            self.sock.settimeout(self.timeout)
                            print("Novo valor de timeout:", self.timeout)
                            print("ACK do pacote final recebido.")
                            if self.exponencial:
                                self.cwnd = self.cwnd * 2
                            else:
                                self.cwnd = self.cwnd + 1
                        else:
                            self.listaACKs.append(pacote.conteudo['ack_n'])
                            if self.checaACKs():
                                if self.cwnd > 1:
                                    self.cwnd /= 2
                                    self.ssthresh = self.cwnd * self.MSS / 2
                                self.exponencial = False
                                for i in range(len(self.buffer)):
                                    if self.buffer[i][
                                            'seq'] == pacote.conteudo[
                                                'ack_n'] - 1:
                                        self.indiceBuffer = i
                                        break
                                print("3 ACKs duplicados. Fast Recovery.")
                                self.listaACKs = []
                            else:
                                if self.exponencial:
                                    self.cwnd = self.cwnd * 2
                                else:
                                    self.cwnd = self.cwnd + 1

                    else:
                        pacote.set([['ack', 1], ['ack_n', self.ack],
                                    ['seq', self.seq], ['dados', ''],
                                    ['RTT', time.time()]])
                        self.buffer.append(pacote.conteudo)
                        print("Esse pacote não era esperado, enviando ACK.")

                    cont += 1
Exemple #3
0
    def iniciar_servidor(self, ip, porta):
        tupla_conn = (ip, porta)
        self.sock.bind(tupla_conn)
        self.sock.settimeout(5)
        pacote = Pacote()
        montador = []
        print("Olá! Servidor iniciando na porta", porta)

        # Recebe dados até que uma conexão seja estabelecida e posteriormente finalizada
        while True:
            cont = 0
            # Loop que recebe os dados
            while cont < self.cwnd:
                if self.cwnd * self.MSS > self.ssthresh:
                    self.exponencial = False
                while True:
                    try:
                        raw_pacote, conn = self.sock.recvfrom(self.MTU)
                        break
                    except:
                        self.ssthresh = self.cwnd * self.MSS / 2
                        self.exponencial = True
                        self.cwnd = 1

                pacote.conteudo = json.loads(raw_pacote)
                pacote.set([['porta_orig', pacote.conteudo['porta_dest']],
                            ['port_dest', conn[1]]])
                if pacote.conteudo['flags']['syn']:
                    print(conn[0], "deseja se conectar.")
                    self.ack = pacote.conteudo['seq'] + 1
                    self.timeout = min(
                        8, round(4 * (time.time() - pacote.conteudo['RTT']),
                                 4))
                    pacote.set([['ack', 1], ['rwnd', 32768], ['seq', self.seq],
                                ['ack_n', self.ack], ['RTT', self.timeout]])
                    raw_pacote = json.dumps(pacote.conteudo)
                    self.sock.settimeout(self.timeout)
                    self.sock.sendto(raw_pacote, conn)
                    print("Pacote SYN ACK enviado.")
                    while True:
                        try:
                            raw_pacote, conn = self.sock.recvfrom(self.MTU)
                            break
                        except:
                            print("Timeout, iniciando a partida lenta")
                            self.ssthresh = self.cwnd * self.MSS / 2
                            self.exponencial = True
                            self.cwnd = 1
                            self.sock.sendto(raw_pacote, tupla_conn)

                    pacote.conteudo = json.loads(raw_pacote)
                    if pacote.conteudo['flags']['ack'] and pacote.conteudo[
                            'ack_n'] - 1 == self.seq:
                        print("Conexão estabelecida!")
                    else:
                        print("Erro ao estabelecer conexão!")
                        break

                elif pacote.conteudo['flags']['fin']:
                    raw_pacote = json.dumps(pacote.conteudo)
                    self.sock.sendto(raw_pacote, conn)
                    print("O cliente gostaria de encerrar a conexão.")
                    self.sock.close()
                    print("Conexão encerrada.")
                    exit()
                else:
                    if self.ack - 1 == pacote.conteudo['seq']:
                        print("Pacote recebido de tamanho",
                              len(pacote.conteudo['dados']))
                        if pacote.conteudo['flags']['ack']:
                            if self.seq == pacote.conteudo['ack_n'] - 1:
                                self.ack += len(pacote.conteudo['dados'])
                                #self.buffer.append(pacote.conteudo)
                                montador.append(pacote.conteudo['dados'])
                                self.timeout = min(
                                    8,
                                    round(
                                        4 *
                                        (time.time() - pacote.conteudo['RTT']),
                                        4))
                                pacote.set([['ack', 1], ['ack_n', self.ack],
                                            ['seq', self.seq], ['dados', ''],
                                            ['RTT', self.timeout]])
                                self.buffer.append(
                                    pacote.conteudo)  #Adicionado
                                self.seq += len(pacote.conteudo['dados'])
                                print("Remontando pacote.")
                                print(
                                    "Numero de bytes após remontagem do pacote:",
                                    len("".join(montador)))  # Trocar
                                print("Primeiros 100 caracteres: ",
                                      "".join(montador)[0:100])
                                if self.exponencial:
                                    self.cwnd = self.cwnd * 2
                                else:
                                    self.cwnd = self.cwnd + 1
                                montador = []
                                break
                            else:
                                self.listaACKs.append(pacote.conteudo['ack_n'])
                                if self.checaACKs() == True:
                                    if self.cwnd > 1:
                                        self.cwnd /= 2
                                        self.ssthresh = self.cwnd * self.MSS / 2
                                    for i in range(len(self.buffer)):
                                        if self.buffer[i][
                                                'ack_n'] == pacote.conteudo[
                                                    'ack_n'] - 1:
                                            self.indiceBuffer = i
                                    print("3 ACKs duplicados. Fast Recovery.")
                        else:
                            self.ack += len(pacote.conteudo['dados'])
                            montador.append(pacote.conteudo['dados'])
                            pacote.set([['ack_n', self.ack], ['seq', self.seq],
                                        ['ack', 0], ['dados', '']])
                            self.buffer.append(pacote.conteudo)
                            if self.exponencial:
                                self.cwnd = self.cwnd * 2
                            else:
                                self.cwnd = self.cwnd + 1
                            print(
                                "O pacote é um segmento, esperando mais dados..."
                            )

                    else:
                        pacote.set([['ack', 1], ['ack_n', self.ack],
                                    ['seq', self.seq], ['dados', '']])
                        self.buffer.append(pacote.conteudo)
                        '''raw_pacote = json.dumps(pacote.conteudo)
						self.sock.sendto(raw_pacote, conn)'''
                        print("O pacote não era esperado, enviando ACK.")
                        self.listaACKs.append(self.ack)
                        if self.checaACKs():
                            if self.cwnd > 1:
                                self.cwnd /= 2
                                self.ssthresh = self.cwnd * self.MSS / 2
                            self.exponencial = False
                            print(
                                "Foram enviados 3 ACKs duplicados, cortando janela."
                            )
                            self.listaACKS = []

                cont += 1

            pacotes_recebidos = cont + 1
            cont = 0

            if not self.buffer:
                print("O buffer está vazio.")
            else:
                # Loop que envia os dados de acordo com a cwnd
                while self.indiceBuffer < len(self.buffer):
                    while cont < pacotes_recebidos:
                        if self.indiceBuffer >= len(self.buffer):
                            break
                        raw_pacote = json.dumps(self.buffer[self.indiceBuffer])
                        self.sock.sendto(raw_pacote, conn)
                        self.indiceBuffer += 1
                        cont += 1

                    print("Enviados", cont, "ACK's")