Editar | Versões

Camada de Transporte - Prática com TCP

Como bem sabemos, todo programa que está rodando no momento é chamado de processo. Desse modo, o navegador que você está utilizando, o spotify, o próprio Windows e os demais softwares são transformados em processos quando os iniciamos. Agora, imagine que um processo precisa enviar uma mensagem para outro processo. Imagine o cenário abaixo:

 

Um sistema de segurança, instalado em uma casa, com um sensor de presença, precisa enviar uma mensagem de alerta para outro processo que está rodando no celular do dono quando disparado.

 


 

Vamos entender como isso ocorre por baixo dos panos.

 

Inicialmente, o processo que está ligado ao sistema de alarme deve se associar a uma porta para poder enviar dados através da rede. O computador possui um total de 65386 portas para que os processos possam se associar. Quem gerencia essas portas e autoriza ou não a associação dos processos é o próprio sistema operacional. Observe a imagem abaixo:



 

 

As portas são identificadores numéricos que identificam unicamente um processo que troca informações na rede através de um endereço IP. Desse modo, para que um processo possa se comunicar com outro processo, é necessário que ele esteja associado a um endereço IP a uma porta de entrada de dados. Esse par de informação (IP, Porta), quando associado a um processo, estabelece uma porta de comunicação chamada Socket, através do qual podemos receber informações da rede.  Vamos utilizar a linguagem python para entender como essa associação ocorre.

 

Implementando um Socket Servidor

 

A partir desse momento, vamos precisar utilizar um interpretador python e um ambiente de desenvolvimento (IDE). Caso você ainda não possua, siga os passos desse tutorial para instalar e depois retorne a este tópico: https://www.devmedia.com.br/instalacao-do-python/40643

Após isso, crie um novo arquivo e salve com o nome server.py.

 

1 - Importe a biblioteca de sockets

 

import socket

 

Você vai encontrar essa biblioteca na maioria das linguagens, mudando apenas a sintaxe. Ela fornecerá as funções de associação dos processos às portas e a escuta de pedidos de conexão externos.

 

2 - Declare constantes com o endereço IP e a Porta para associar o processo servidor

HOST = “127.0.0.1”

PORTA = 5000

O IP 127.0.0.1 é um endereço reservado para quando queremos que a troca de mensagens seja entre dois processos em um mesmo computador. Também chamamos esse endereço de host local ou localhost.

 

3 - Vamos criar um objeto socket utilizando o protocolo de transporte TCP.

 

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

A função socket(ProtocoloCamada3, ProtocoloCamada4) recebe dois parâmetros. O primeiro identifica o protocolo de camada 3 como o IP, definido como socket.AF_INET. O segundo parâmetro informa qual protocolo de transporte será utilizado. Neste caso é o protocolo de transporte confiável, o TCP, identificado como socket.SOCK_STREAM.

4 - Neste ponto, já temos nosso objeto socket mas ele ainda não está associado ao IP e à Porta para conseguir trocar informações na rede. Utilize a função bind() para isso com as constantes HOST e PORTA.

 

tcpSocket.bind((HOST, PORTA))

 

5 -  Neste ponto, nosso socket já está apto a trocar informações pela porta 5000, porém, ainda precisamos colocá-lo em modo de escuta. Assim, ele ficará escutando a chegada de novos pedidos para só então receber e enviar dados. Utilize a função listen() para isso. Informe como parâmetro a quantidade de conexões simultâneas que serão atendidas.

tcpSocket.listen(1)

 

O número 1, que informamos como parâmetro da função listen(), informa que apenas uma conexão poderá ser estabelecida por vez.

 

Neste ponto, vamos programar o que o nosso socket servidor fará alguém tentar se conectar a ele. Vamos utilizar as funções accept() para receber essa conexão e depois a função recv() para receber os dados enviados pelo processo cliente. A lógica será a seguinte:
 

Vincule-se a um IP e a uma porta  para receber conexões (bind())

Entre em modo de escuta por conexões (listen())

Enquanto o programa estiver rodando

    Aguarde um pedido de conexão (accept())

    se houver um processo solicitando conexão, então

            Receba a conexão

            Enquanto o cliente estiver enviando dados:

                    Receba a mensagem (receive()), decodifique e mostre na tela

        Não havendo mais mensagens para ser recebida, encerre a conexão (close())

        Retorne e aguarde o próximo pedido de conexão

 

Veja a representação gráfica desse algoritmo:

 

Agora veja o algoritmo acima em python:

while True:

    sockCliente, enderecoCliente = tcpSocket.accept() # coloca o socket em espera por uma conexão de algum cliente

    print('Conectado por ', enderecoCliente)

    while True:

        msg = sockCliente.recv(1024) # recebe uma mensagem enviada pelo cliente

        if not msg: break

        print(enderecoCliente, " > ", msg.decode('utf-8'))

    print("Finalizando conexão com ", sockCliente)

    sockCliente.close()# finaliza a conexão com o cliente

 

 

Código Cliente TCP

import socket
HOST = '127.0.0.1' # Endereco IP do Servidor;
PORT = 5000 # Porta que o Servidor está escutando;
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
destino = (HOST, PORT) # Variável do tipo "Lista" com duas posições, armazenando IP do servidor e porta: [127.0.0.1, 5000];
tcpSocket.connect(destino) # Faz a conexão com o servidor no IP e na PORTA definidos pela variável "destino";
print('Para sair use CTRL+X\n')
msg = input() # Lê uma mensagem da entrada padrão (equivalente ao "scanf()" do C);
while msg != '\x18': # Enquanto a mensagem é diferente de \x18 (ctrl + x), envia a mensagem e lê a próxima;
    tcpSocket.sendall(msg.encode('utf-8')) # Envia o texto da variável "msg" para o servidor, codificado como utf-8;
    msg = input() # Lê a próxima mensagem que será enviada no "while";
tcpSocket.close() # Encerra a conexão com servidor após a finalização do While.

 


Comentários...

Não há comentários ainda... Seja o primeiro!