Socket em Python, criando um Chat

Tutorial para a criação de um chat simples utilizando sockets TCP e UDP em Python 3. O objetivo é mostrar a comunicação unidirecional, onde um cliente envia mensagens para um servidor.

Aprender a usar sockets em python é uma ótima forma de combinar os conhecimentos de programação e redes.

Criando o chat em TCP

Primeiramente vamos mostrar como criar um chat usando o TCP. O legal do TCP é que esse protocolo vai lidar com os erros e perdas de segmentos durante a execução do chat.

Isso significa que se houver perda de pacotes na rede o TCP vai tratar isso para nós e consequentemente não vamos ter erros provocados por esse tipo de perda em nosso chat.

Explicando o servidor do chat em TCP

Agora, vamos mostrar o código do servidor do chat em python. Depois, vamos mostrar como executar o código e posteriormente vamos explicar o código.

#!/usr/bin/python3
import socket

# Solicitar a porta que o servidor deve ouvir
MINHA_PORTA = int(input("Digite a porta que o servidor deve ouvir: "))

MEU_IP = ''  # Endereco IP do Servidor, '' significa que ouvirá em todas as interfaces

# Criar o socket TCP
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Definir o IP e porta para o servidor ouvir
MEU_SERVIDOR = (MEU_IP, MINHA_PORTA)
tcp.bind(MEU_SERVIDOR)  # Faz o bind do IP e da porta para começar a ouvir

tcp.listen(1)  # Começar a ouvir (aguardar conexão)

print(f"Servidor ouvindo na porta {MINHA_PORTA}...")

# Aceitar conexão do cliente
conexao, docliente = tcp.accept()
print("O cliente =", docliente, "se conectou")

# Loop para receber mensagens do cliente
while True:
    Mensagem_Recebida = conexao.recv(1024)
    if Mensagem_Recebida:
        # Se houver uma nova mensagem, imprime na tela
        print("Recebi =", Mensagem_Recebida.decode("utf8"), ", Do cliente", docliente)

# Fechar a conexão ao terminar
conexao.close()

Executando o servidor socket TCP no Windows

Agora vamos abrir um editor do Windows. Nesse caso, estamos usando o Notepad para colar o código que copiamos. Depois de colar o código acima, clique em “save as“.

Em seguida, vamos dar o nome “server.py” e vamos clicar em salvar. Lembre-se do local onde você está salvando o arquivo.

Agora, vamos no local onde você salvou o arquivo “server.py” e vamos dar um duplo click com o mouse para executa-lo. Depois de executar o “server.py” vamos escolher a porta que o servidor vai ouvir.

Nesse caso, estamos fazendo o servidor ouvir na porta 4040.

Lembre-se de permitir o acesso no Windows Defender Firewall. Nesse caso, você pode escolher entre acesso somente para rede privada ou acesso para redes públicas. Veja qual acesso atende melhor o seu laboratório de prática.

Executando o servidor socket TCP no Linux

Em uma máquina com o Linux, podemos abrir o terminal e digitar o comando abaixo. E depois cole o código do servidor que você copiou acima.

nano server.py

Depois de colar o código e salvar, vamos executar o “server.py”. Para isso, vamos digitar o comando abaixo.

python3 server.py

Podemos observar que o servidor está ouvindo na porta 4040 e aguardando conexões.

Explicando o código do servidor socket TCP

Agora vamos explicar o código do servidor socket TCP do nosso chat.

Inicialmente vamos perguntar qual vai ser a porta que o servidor vai ouvir. Minha sugestão é que utilize portas altas como por exemplo 4040.

# Solicitar a porta que o servidor deve ouvir
MINHA_PORTA = int(input(“Digite a porta que o servidor deve ouvir: “))

Depois vamos criar o socket TCP que será do tipo IPv4 =”AF_INET” e será TCP = “SOCK_STREAM“.

# Criar o socket TCP
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Agora, vamos configurar o IP e a porta que desejamos monitorar. Neste caso, estamos considerando que o IP será “0.0.0.0”, ou seja, o servidor ficará escutando na porta especificada em todos os IPs disponíveis na máquina.

# Definir o IP e porta para o servidor ouvir
MEU_SERVIDOR = (MEU_IP, MINHA_PORTA)
tcp.bind(MEU_SERVIDOR) # Faz o bind do IP e da porta para começar a ouvir

tcp.listen(1) # Começar a ouvir (aguardar conexão)

Em seguida vamos armazenar dados da conexão em duas variáveis. A variável “docliente” armazena o IP do cliente e a variável “conexao” apresenta dados da conexão.

# Aceitar conexão do cliente
conexao, docliente = tcp.accept()

Em seguida, vamos ver o loop que aguarda as mensagens recebidas que são colhidas com a variável “conexao“.

# Loop para receber mensagens do cliente
while True:
Mensagem_Recebida = conexao.recv(1024)
if Mensagem_Recebida:
# Se houver uma nova mensagem, imprime na tela
print(“Recebi =”, Mensagem_Recebida.decode(“utf8”), “, Do cliente”, docliente)

  • recv(1024) = lê até 1024 bytes da mensagem enviada pelo cliente através do socket conexao.
  • Mensagem_Recebida.decode(“utf8”) = decodificada de bytes para string a mensagem recebida;

Por último temos a finalização da conexão usando o socket “conexao“.

# Fechar a conexão ao terminar
conexao.close()

Explicando o cliente do chat em TCP

Em seguida, vamos mostrar o código do cliente do chat em python e depois como executa-lo.

#!/usr/bin/python3
import socket

# Solicitar IP e porta do servidor ao usuário
IP_Servidor = input("Digite o endereço IP do servidor: ")
PORTA_Servidor = int(input("Digite a porta do servidor: "))

# Criar o socket TCP
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp.settimeout(10)  # Definir timeout de 10 segundos

# Destino da conexão (IP + Porta)
DESTINO = (IP_Servidor, PORTA_Servidor)

try:
    # Conectar ao servidor
    tcp.connect(DESTINO)
    print(f"Conectado ao servidor {IP_Servidor}:{PORTA_Servidor}.")
    print("Você pode começar a enviar mensagens (digite 'sair' para desconectar).")

    # Loop principal para enviar mensagens
    while True:
        Mensagem = input("Digite sua mensagem: ")
        if Mensagem.lower() == 'sair':
            print("Desconectando...")
            break
        tcp.send(bytes(Mensagem, "utf8"))
except socket.error as e:
    print(f"Erro ao conectar ou enviar dados: {e}")
finally:
    tcp.close()
    print("Conexão encerrada.")

Executando o cliente socket TCP no Windows

Vamos abrir um editor como o Notepad e vamos colar o código que copiamos acima. Depois vamos clicar em salvar.

Nesse momento, vamos escolher o local onde vamos criar o arquivo e o nome. Nesse caso vamos usar o nome “client.py“.

Agora, vamos até o diretório onde você salvou o “client.py” e podemos dar um duplo click no client para executa-lo.

Ao executar o “client.py” vamos indicar o IP do servidor. Nesse caso, estamos usando o endereço de loopback o “127.0.0.1” mas você pode escolher o IP de uma máquina da sua rede que esteja executando o “server.py“.

Em seguida, vamos digitar a porta que o servidor está ouvindo, que nesse nosso exemplo foi a porta 4040.

Depois enviamos uma mensagem “hello“.

Podemos ver na figura acima que o servidor recebeu a mensagem “hello” que o cliente enviou.

Executando o cliente socket TCP no linux

Para executar o cliente no Linux, vamos abrir um terminal e usar um editor. Em nosso caso estamos usando o editor “nano”. Assim, vamos digitar o comando abaixo para criar e editar o arquivo “client.py“.

nano client.py

Depois de abrir o editor, vamos colar o código do cliente que copiamos acima e depois salvar.

Agora, vamos executar o “client.py” usando o comando abaixo.

python3 client.py

Ao executar o “client.py” vamos indicar o IP do servidor. Nesse caso, estamos usando o endereço de loopback o “127.0.0.1” mas você pode escolher o IP de uma máquina da sua rede que esteja executando o “server.py“.

Em seguida, vamos digitar a porta que o servidor está ouvindo, que nesse nosso exemplo foi a porta 4040.

Agora, vamos digitar “hello” no cliente.

Podemos perceber que o servidor “server.py” recebeu o “hello” do cliente.

Explicando o código do cliente socket TCP

Inicialmente estamos pedindo que o usuário indique o IP e a porta que o cliente vai se conectar. Nesse caso, vamos inserir o IP do servidor e a porta que o servidor está ouvindo.

# Solicitar IP e porta do servidor ao usuário
IP_Servidor = input(“Digite o endereço IP do servidor: “)
PORTA_Servidor = int(input(“Digite a porta do servidor: “))

Agora, vamos criar o socket TCP e configurar um “timeout” como tempo máximo que o TCP vai aguardar sem conexão.

# Criar o socket TCP
tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp.settimeout(10) # Definir timeout de 10 segundos

A primeira linha cria um socket para comunicação entre cliente e servidor usando:

  • AF_INET = IPv4 como família de endereços.
  • SOCK_STREAM = TCP como protocolo de comunicação, o que significa que a comunicação será orientada a conexão, confiável, e com controle de fluxo.
  • tcp.settimeout(10) = Define o tempo que vai aguardar pela conexão como 10 segundos.

Em seguida, vamos criar a variável que vai ser usada como o destino da comunicação TCP. Nesse caso temos a combinação do IP e porta do servidor.

# Destino da conexão (IP + Porta)
DESTINO = (IP_Servidor, PORTA_Servidor)

Em seguida, vamos para a função que vai conectar ao servidor “tcp.connect“. Essa função recebe como parâmetro o conjunto I(P + porta do servidor) que definimos anteriormente como “DESTINO“.

# Conectar ao servidor
tcp.connect(DESTINO)

A seguir, vamos ver o trecho do código que permite ao usuário enviar várias mensagens ao servidor até que ele decida encerrar a conexão.

# Loop principal para enviar mensagens
while True:
Mensagem = input(“Digite sua mensagem: “)
if Mensagem.lower() == ‘sair’:
print(“Desconectando…”)
break
tcp.send(bytes(Mensagem, “utf8”))

  • input() = Solicita ao usuário que digite uma mensagem.
  • Se o usuário digitar “sair” o programa sai do loop com o break.
  • tcp.send() = função para enviar a mensagem.
  • bytes(Mensagem, “utf8”) = A mensagem é convertida para bytes para ser enviada pela rede.

Depois vamos ter a função parra verificar se houve erro no socket “except socket.error ” e por fim, teremos a função para finalizar o socket com “tcp.close()

except socket.error as e:
print(f”Erro ao conectar ou enviar dados: {e}”)
finally:
tcp.close()

Leia mais:

Qual a melhor IDE para Python?

Python: como obter metadados de imagens e PDFs

Mesclando arquivos PDFs: REGEX e PyPDF2 com Python

Criando CRUD MySQL com Python

Conectando ao MySQL com Python

Juliana Mascarenhas

Data Scientist and Master in Computer Modeling by LNCC.
Computer Engineer