Como enviar e receber mensagens usando sockets Python

PythonBeginner
Pratique Agora

Introdução

Sockets Python fornecem uma ferramenta poderosa para comunicação em rede, permitindo que você envie e receba mensagens através de diferentes sistemas. Neste tutorial, vamos guiá-lo através do processo de uso de sockets Python para estabelecer conexões, transmitir dados e receber respostas. Ao final deste laboratório, você terá construído tanto uma aplicação cliente quanto uma aplicação servidor que podem se comunicar entre si através de uma rede.

Este conhecimento prático forma a base para o desenvolvimento de aplicações em rede mais complexas, desde programas de chat até sistemas distribuídos.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível intermediário com uma taxa de conclusão de 71%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Entendendo os Fundamentos de Sockets e Criando Seu Primeiro Socket

Vamos começar entendendo o que são sockets e como eles funcionam em Python. Em seguida, criaremos nosso primeiro socket para ver como ele é inicializado.

O que são Sockets Python?

Sockets são pontos finais para enviar e receber dados através de uma rede. Eles fornecem uma interface de programação para comunicação em rede, permitindo que aplicações troquem informações, independentemente de sua localização.

Na programação de rede, normalmente usamos um modelo cliente-servidor:

  • O servidor espera por conexões de entrada e processa requisições
  • O cliente inicia a comunicação conectando-se ao servidor

O módulo socket embutido do Python facilita o trabalho com sockets sem a necessidade de entender todos os detalhes complexos dos protocolos de rede.

Tipos de Socket

Os dois tipos de socket mais comuns são:

  • TCP (Transmission Control Protocol): Fornece entrega de dados confiável e ordenada
  • UDP (User Datagram Protocol): Fornece transmissão de dados mais rápida, mas não confiável

Para este laboratório, focaremos em sockets TCP, que são o tipo mais comumente usado para aplicações que exigem comunicação confiável.

Criando Seu Primeiro Socket

Vamos criar um script Python simples para inicializar um socket. Abra o WebIDE e siga estes passos:

  1. Primeiro, vamos criar um diretório para nosso projeto de programação de sockets:
mkdir -p ~/project/socket_lab
cd ~/project/socket_lab
  1. Agora, crie um novo arquivo Python chamado socket_basics.py:

No WebIDE, clique no botão "New File" ou use o menu "File" e selecione "New File", então nomeie-o socket_basics.py dentro do diretório socket_lab.

  1. Adicione o seguinte código para demonstrar como criar um socket:
import socket

## Creating a socket
print("Creating a new socket...")
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(f"Socket created: {my_socket}")

## Explaining the parameters:
print("\nSocket parameters explained:")
print("AF_INET: Using IPv4 addressing")
print("SOCK_STREAM: Using TCP protocol for reliable data transmission")

## Getting available socket methods
print("\nSome methods available on socket objects:")
methods = [method for method in dir(my_socket) if not method.startswith('_')]
print(', '.join(methods[:10]) + '...')  ## Showing first 10 methods

## Closing the socket
my_socket.close()
print("\nSocket closed")
  1. Salve o arquivo.

  2. Execute o script para ver a saída:

python3 ~/project/socket_lab/socket_basics.py

Você deve ver uma saída semelhante a esta:

Creating a new socket...
Socket created: <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>

Socket parameters explained:
AF_INET: Using IPv4 addressing
SOCK_STREAM: Using TCP protocol for reliable data transmission

Some methods available on socket objects:
accept, bind, close, connect, connect_ex, detach, fileno, getpeername, getsockname, getsockopt...

Socket closed

Esta saída mostra que criamos com sucesso um objeto socket e exploramos algumas de suas propriedades. Nas próximas seções, usaremos sockets para construir uma aplicação servidor e cliente que podem se comunicar entre si.

Funções Chave de Socket

Antes de prosseguir, vamos entender algumas funções chave de socket que usaremos:

  • socket() - Cria um novo objeto socket
  • bind() - Associa o socket a uma interface de rede e porta específicas
  • listen() - Permite que o servidor aceite conexões
  • accept() - Aceita uma conexão de um cliente
  • connect() - Conecta-se a um endereço remoto
  • send() - Envia dados para um socket conectado
  • recv() - Recebe dados de um socket conectado
  • close() - Fecha o socket

No próximo passo, criaremos um servidor usando essas funções.

Criando um Servidor Socket Simples

Agora que entendemos os fundamentos de sockets, vamos criar um servidor simples que escuta por conexões e recebe mensagens de clientes.

Como um Servidor Socket Funciona

Um servidor socket segue estes passos gerais:

  1. Criar um socket
  2. Vincular (bind) a um endereço e porta
  3. Escutar por conexões de entrada
  4. Aceitar conexões de clientes
  5. Receber e processar dados
  6. Enviar uma resposta, se necessário
  7. Fechar a conexão

Vamos implementar este padrão em Python.

Criando o Servidor

  1. Crie um novo arquivo Python chamado server.py no diretório socket_lab:

No WebIDE, clique no botão "New File" ou use o menu "File" e selecione "New File", então nomeie-o server.py dentro do diretório socket_lab.

  1. Adicione o seguinte código para criar um servidor básico:
import socket

def start_server():
    ## Server configuration
    host = '127.0.0.1'  ## localhost
    port = 12345        ## arbitrary non-privileged port

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set socket option to reuse address (helps avoid "Address already in use" errors)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    ## Bind socket to address and port
    server_socket.bind((host, port))

    ## Listen for connections (queue up to 5 connection requests)
    server_socket.listen(5)

    print(f"Server started on {host}:{port}")
    print("Waiting for client connection...")

    try:
        ## Accept connection
        client_socket, client_address = server_socket.accept()
        print(f"Connection established with {client_address}")

        ## Receive data from client
        data = client_socket.recv(1024)  ## receive up to 1024 bytes
        print(f"Message received: {data.decode()}")

        ## Send response to client
        response = "Message received by server"
        client_socket.send(response.encode())

        ## Close client connection
        client_socket.close()

    except KeyboardInterrupt:
        print("\nServer shutting down...")
    finally:
        ## Close server socket
        server_socket.close()
        print("Server socket closed")

if __name__ == "__main__":
    start_server()
  1. Salve o arquivo.

Entendendo o Código do Servidor

Vamos detalhar os componentes-chave do nosso servidor:

  • Criação do Socket: Criamos um socket TCP usando socket.socket() com AF_INET (IPv4) e SOCK_STREAM (protocolo TCP).

  • Opções do Socket: Definimos uma opção para reutilizar o endereço, o que ajuda a evitar erros "Address already in use" ao reiniciar o servidor rapidamente após o desligamento.

  • Vinculação (Binding): Vinculamos o socket ao endereço 127.0.0.1 (localhost) e à porta 12345. Isso informa ao sistema operacional que queremos receber conexões neste local de rede específico.

  • Escuta (Listening): A chamada listen(5) diz ao socket para enfileirar até 5 solicitações de conexão antes de recusar novas conexões.

  • Aceitando Conexões: O método accept() bloqueia (espera) até que um cliente se conecte, então retorna um novo objeto socket para se comunicar com esse cliente, juntamente com o endereço do cliente.

  • Recebendo Dados: Usamos recv(1024) para receber até 1024 bytes de dados do cliente. Os dados vêm como bytes, então usamos decode() para convertê-los em uma string.

  • Enviando Dados: Enviamos uma resposta de volta ao cliente usando o método send(). Usamos encode() para converter a string em bytes antes de enviar.

  • Fechamento: Finalmente, fechamos tanto o socket do cliente quanto o socket do servidor para liberar recursos.

Testando o Servidor

Vamos executar nosso servidor para vê-lo em ação. Ele não fará muita coisa ainda, pois não criamos um cliente, mas podemos verificar se ele inicia corretamente:

python3 ~/project/socket_lab/server.py

Você deve ver uma saída como esta:

Server started on 127.0.0.1:12345
Waiting for client connection...

O servidor agora está esperando que um cliente se conecte. Como ainda não temos um cliente, pressione Ctrl+C para parar o servidor:

^C
Server shutting down...
Server socket closed

No próximo passo, criaremos um cliente para se conectar ao nosso servidor.

Construindo um Cliente para Conectar ao Servidor

Agora que temos nosso servidor, precisamos criar um cliente que possa se conectar a ele e enviar mensagens. Vamos construir uma aplicação cliente simples.

Como um Cliente Socket Funciona

Um cliente socket segue estes passos gerais:

  1. Criar um socket
  2. Conectar ao endereço e porta de um servidor
  3. Enviar dados
  4. Receber uma resposta
  5. Fechar a conexão

Criando o Cliente

  1. Crie um novo arquivo Python chamado client.py no diretório socket_lab:

No WebIDE, clique no botão "New File" ou use o menu "File" e selecione "New File", então nomeie-o client.py dentro do diretório socket_lab.

  1. Adicione o seguinte código para criar um cliente básico:
import socket

def start_client():
    ## Server information to connect to
    host = '127.0.0.1'  ## localhost - same as server
    port = 12345        ## same port as server

    try:
        ## Create socket
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        ## Connect to server
        print(f"Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))
        print("Connected to server")

        ## Send a message
        message = "Hello from the client!"
        print(f"Sending message: {message}")
        client_socket.send(message.encode())

        ## Receive response
        response = client_socket.recv(1024)
        print(f"Response from server: {response.decode()}")

    except ConnectionRefusedError:
        print("Connection failed. Make sure the server is running.")
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        ## Close socket
        client_socket.close()
        print("Connection closed")

if __name__ == "__main__":
    start_client()
  1. Salve o arquivo.

Entendendo o Código do Cliente

Vamos examinar as partes-chave do nosso código cliente:

  • Criação do Socket: Semelhante ao servidor, criamos um socket TCP usando socket.socket().

  • Conexão: Em vez de vincular e escutar, o cliente usa connect() para estabelecer uma conexão com o servidor no host e porta especificados.

  • Enviando Dados: Enviamos uma mensagem usando o método send(), certificando-se de codificar a string em bytes.

  • Recebendo Dados: Usamos recv(1024) para receber a resposta do servidor e decodificá-la de volta para uma string.

  • Tratamento de Erros: Incluímos tratamento de erros para capturar problemas comuns, como o servidor não estar disponível (ConnectionRefusedError).

  • Fechamento: Fechamos o socket quando terminamos para liberar recursos.

Testando Cliente e Servidor Juntos

Agora vamos testar nosso cliente e servidor juntos. Precisaremos executá-los em janelas de terminal separadas.

  1. Primeiro, inicie o servidor:
python3 ~/project/socket_lab/server.py

Você deve ver:

Server started on 127.0.0.1:12345
Waiting for client connection...
  1. Abra um novo terminal no WebIDE (clicando no botão "+" no painel do terminal) e execute o cliente:
python3 ~/project/socket_lab/client.py

Você deve ver uma saída como esta no terminal do cliente:

Connecting to server at 127.0.0.1:12345...
Connected to server
Sending message: Hello from the client!
Response from server: Message received by server
Connection closed

E no terminal do servidor, você deve ver:

Connection established with ('127.0.0.1', 55234)  ## The port number may differ
Message received: Hello from the client!

Depois que o cliente se desconectar, o servidor parará porque nossa implementação atual lida apenas com uma única conexão. Pressione Ctrl+C no terminal do servidor para desligá-lo, se ainda estiver em execução.

Isso demonstra a comunicação bem-sucedida entre um cliente e um servidor usando sockets Python. O cliente é capaz de enviar uma mensagem ao servidor, e o servidor pode recebê-la e enviar uma resposta de volta.

Construindo um Servidor Contínuo e um Cliente Interativo

Nossa implementação atual de servidor-cliente lida apenas com uma única troca de mensagens antes de fechar. A maioria das aplicações do mundo real precisa manter conexões e lidar com múltiplas mensagens. Vamos aprimorar nosso código para criar uma experiência mais interativa.

Aprimorando o Servidor

Primeiro, vamos modificar nosso servidor para aceitar continuamente conexões e lidar com múltiplas mensagens de cada cliente.

  1. Abra o arquivo server.py no WebIDE e substitua o código por:
import socket

def start_server():
    ## Server configuration
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        ## Bind and listen
        server_socket.bind((host, port))
        server_socket.listen(5)

        print(f"Server running on {host}:{port}")
        print("Press Ctrl+C to stop the server")

        while True:  ## Continuous server loop
            print("\nWaiting for a connection...")
            client_socket, client_address = server_socket.accept()
            print(f"Connected to client: {client_address}")

            ## Handle client communication
            handle_client(client_socket)

    except KeyboardInterrupt:
        print("\nServer is shutting down...")
    finally:
        server_socket.close()
        print("Server closed")

def handle_client(client_socket):
    try:
        while True:  ## Keep receiving messages until client disconnects
            ## Receive data
            data = client_socket.recv(1024)

            ## If no data, client has disconnected
            if not data:
                break

            received_message = data.decode()
            print(f"Received: {received_message}")

            ## Process the message (in this case, just echo it back with a prefix)
            response = f"Server received: {received_message}"
            client_socket.send(response.encode())

    except Exception as e:
        print(f"Error handling client: {e}")
    finally:
        ## Close client socket
        client_socket.close()
        print("Client connection closed")

if __name__ == "__main__":
    start_server()
  1. Salve o arquivo.

Aprimorando o Cliente

Agora, vamos criar um cliente interativo que permite aos usuários enviar múltiplas mensagens.

  1. Abra o arquivo client.py no WebIDE e substitua o código por:
import socket

def start_client():
    ## Server information
    host = '127.0.0.1'
    port = 12345

    try:
        ## Create socket and connect
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print(f"Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))
        print("Connected to server!")

        ## Interactive message sending
        while True:
            ## Get message from user
            message = input("\nEnter message to send (or 'quit' to exit): ")

            ## Check if user wants to quit
            if message.lower() == 'quit':
                print("Closing connection...")
                break

            ## Send message
            client_socket.send(message.encode())

            ## Receive response
            response = client_socket.recv(1024)
            print(f"Response from server: {response.decode()}")

    except ConnectionRefusedError:
        print("Connection failed. Make sure the server is running.")
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        ## Close connection
        try:
            client_socket.close()
        except:
            pass
        print("Disconnected from server")

if __name__ == "__main__":
    start_client()
  1. Salve o arquivo.

Entendendo o Código Aprimorado

Aprimoramentos do Servidor:

  • Adicionamos um loop while True externo para aceitar continuamente novas conexões de clientes
  • Criamos uma função handle_client separada para gerenciar a comunicação com cada cliente
  • A função de tratamento do cliente tem seu próprio loop para receber múltiplas mensagens do mesmo cliente
  • Verificamos dados vazios (if not data:), o que indica que o cliente se desconectou

Aprimoramentos do Cliente:

  • Adicionamos um loop while True para permitir o envio de múltiplas mensagens
  • Solicitamos a entrada do usuário e a enviamos ao servidor
  • O usuário pode digitar 'quit' para sair do loop e fechar a conexão
  • Após enviar cada mensagem, esperamos e exibimos a resposta do servidor

Testando as Aplicações Aprimoradas

Vamos testar nosso servidor e cliente aprimorados:

  1. Inicie o servidor aprimorado em um terminal:
python3 ~/project/socket_lab/server.py

Você deve ver:

Server running on 127.0.0.1:12345
Press Ctrl+C to stop the server

Waiting for a connection...
  1. Em um novo terminal, execute o cliente aprimorado:
python3 ~/project/socket_lab/client.py

Você deve ver:

Connecting to server at 127.0.0.1:12345...
Connected to server!

Enter message to send (or 'quit' to exit):
  1. Digite uma mensagem e pressione Enter:
Enter message to send (or 'quit' to exit): Hello, server!
Response from server: Server received: Hello, server!

Enter message to send (or 'quit' to exit):
  1. Tente enviar mais algumas mensagens. No terminal do servidor, você deve ver cada mensagem sendo recebida:
Connected to client: ('127.0.0.1', 59042)
Received: Hello, server!
Received: This is another message
  1. Quando terminar, digite 'quit' no cliente:
Enter message to send (or 'quit' to exit): quit
Closing connection...
Disconnected from server
  1. No terminal do servidor, você deve ver:
Client connection closed

Waiting for a connection...
  1. O servidor continua em execução e está pronto para aceitar novas conexões. Você pode iniciar outro cliente ou pressionar Ctrl+C para parar o servidor.

Com esses aprimoramentos, criamos um sistema de comunicação cliente-servidor mais realista e interativo usando sockets Python.

Múltiplos Clientes e Tratamento de Erros

Em aplicações do mundo real, um servidor normalmente precisa lidar com múltiplos clientes simultaneamente e gerenciar graciosamente várias condições de erro. Vamos melhorar nossa implementação com essas considerações em mente.

Entendendo o Tratamento Concorrente de Clientes

Existem várias maneiras de lidar com múltiplos clientes concorrentemente:

  1. Threading (Encadeamento): Crie uma nova thread para cada conexão de cliente
  2. Process-based (Baseado em Processos): Gere um novo processo para cada cliente
  3. Asynchronous I/O (I/O Assíncrono): Use I/O não bloqueante com um loop de eventos

Para este laboratório, implementaremos uma abordagem baseada em threading, que é relativamente simples de entender e implementar.

Aprimorando o Servidor para Múltiplos Clientes

Vamos modificar nosso servidor para lidar com múltiplos clientes usando threads:

  1. Abra o arquivo server.py no WebIDE e substitua o código por:
import socket
import threading

def handle_client(client_socket, client_address):
    """Handle communication with a single client"""
    try:
        print(f"[NEW CONNECTION] {client_address} connected.")

        while True:
            ## Receive client data
            try:
                data = client_socket.recv(1024)
                if not data:
                    break  ## Client disconnected

                message = data.decode()
                print(f"[{client_address}] {message}")

                ## Send response
                response = f"Message '{message}' received successfully"
                client_socket.send(response.encode())

            except ConnectionResetError:
                print(f"[{client_address}] Connection reset by client")
                break

    except Exception as e:
        print(f"[ERROR] {e}")

    finally:
        ## Clean up when client disconnects
        client_socket.close()
        print(f"[DISCONNECTED] {client_address} disconnected")

def start_server():
    """Start the server and listen for connections"""
    ## Server configuration
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set socket option to reuse address
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        ## Bind to host and port
        server_socket.bind((host, port))

        ## Listen for connections
        server_socket.listen(5)
        print(f"[STARTING] Server is listening on {host}:{port}")

        while True:
            ## Accept client connection
            client_socket, client_address = server_socket.accept()

            ## Create a new thread to handle the client
            client_thread = threading.Thread(
                target=handle_client,
                args=(client_socket, client_address)
            )
            client_thread.daemon = True  ## Thread will close when main program exits
            client_thread.start()

            ## Display active connections
            print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}")

    except KeyboardInterrupt:
        print("\n[SHUTTING DOWN] Server is shutting down...")
    except Exception as e:
        print(f"[ERROR] {e}")
    finally:
        server_socket.close()
        print("[CLOSED] Server socket closed")

if __name__ == "__main__":
    start_server()
  1. Salve o arquivo.

Melhorando o Cliente com Tratamento de Erros

Vamos também aprimorar nosso cliente com melhor tratamento de erros:

  1. Abra o arquivo client.py no WebIDE e substitua o código por:
import socket
import sys
import time

def start_client():
    """Start a client that connects to the server"""
    ## Server information
    host = '127.0.0.1'
    port = 12345

    ## Create socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    ## Set a timeout for connection attempts (5 seconds)
    client_socket.settimeout(5)

    try:
        ## Connect to server
        print(f"[CONNECTING] Connecting to server at {host}:{port}...")
        client_socket.connect((host, port))

        ## Reset timeout to none for regular communication
        client_socket.settimeout(None)

        print("[CONNECTED] Connected to server")

        ## Communication loop
        while True:
            ## Get user input
            message = input("\nEnter message (or 'quit' to exit): ")

            if message.lower() == 'quit':
                print("[CLOSING] Closing connection by request...")
                break

            try:
                ## Send message
                client_socket.send(message.encode())

                ## Wait for response
                response = client_socket.recv(1024)
                print(f"[RESPONSE] {response.decode()}")

            except ConnectionResetError:
                print("[ERROR] Connection was reset by the server")
                break
            except ConnectionAbortedError:
                print("[ERROR] Connection was aborted")
                break
            except Exception as e:
                print(f"[ERROR] {e}")
                break

    except socket.timeout:
        print("[TIMEOUT] Connection attempt timed out. Is the server running?")
    except ConnectionRefusedError:
        print("[REFUSED] Connection refused. Make sure the server is running.")
    except KeyboardInterrupt:
        print("\n[INTERRUPT] Client shutting down...")
    except Exception as e:
        print(f"[ERROR] {e}")

    finally:
        ## Close socket
        try:
            client_socket.close()
            print("[DISCONNECTED] Disconnected from server")
        except:
            pass

if __name__ == "__main__":
    start_client()
  1. Salve o arquivo.

Entendendo o Código Aprimorado

Aprimoramentos do Servidor:

  • Adicionamos o módulo threading para lidar com múltiplos clientes concorrentemente
  • Cada conexão de cliente agora é tratada em uma thread separada
  • Melhoramos o tratamento de erros com capturas de exceção mais específicas
  • Exibimos o número de conexões de clientes ativas
  • As threads são definidas como "daemon", o que significa que elas serão fechadas automaticamente quando o programa principal sair

Aprimoramentos do Cliente:

  • Adicionamos um tempo limite de conexão para evitar travamentos se o servidor não estiver disponível
  • Melhoramos o tratamento de erros com capturas de exceção específicas para diferentes erros de rede
  • Adicionamos mensagens de status mais descritivas com formatação clara

Testando o Servidor Multi-Cliente

Vamos testar nossas aplicações aprimoradas:

  1. Inicie o servidor:
python3 ~/project/socket_lab/server.py

Você deve ver:

[STARTING] Server is listening on 127.0.0.1:12345
  1. Em um novo terminal, inicie um cliente:
python3 ~/project/socket_lab/client.py
  1. Inicie outro cliente em um terceiro terminal:
python3 ~/project/socket_lab/client.py
  1. No terminal do servidor, você deve ver ambas as conexões:
[NEW CONNECTION] ('127.0.0.1', 59124) connected.
[ACTIVE CONNECTIONS] 1
[NEW CONNECTION] ('127.0.0.1', 59126) connected.
[ACTIVE CONNECTIONS] 2
  1. Envie mensagens de ambos os clientes e observe o servidor recebendo-as:
[('127.0.0.1', 59124)] Hello from client 1
[('127.0.0.1', 59126)] Hello from client 2
  1. Quando terminar, digite 'quit' em cada cliente para desconectar ou pressione Ctrl+C no terminal do servidor para desligar o servidor.

Lidando com o Servidor Não em Execução

Vamos também testar o que acontece quando o servidor não está em execução:

  1. Certifique-se de que o servidor esteja parado (pressione Ctrl+C se estiver em execução)

  2. Tente executar um cliente:

python3 ~/project/socket_lab/client.py

Você deve ver:

[CONNECTING] Connecting to server at 127.0.0.1:12345...
[REFUSED] Connection refused. Make sure the server is running.
[DISCONNECTED] Disconnected from server

O cliente agora lida com o erro graciosamente, informando ao usuário que o servidor pode não estar em execução.

Com esses aprimoramentos, criamos um sistema cliente-servidor robusto que pode lidar com múltiplos clientes e várias condições de erro. Esta é uma base sólida para o desenvolvimento de aplicações em rede mais complexas.

Resumo

Parabéns por concluir este laboratório sobre programação de sockets em Python. Você aprendeu com sucesso como:

  1. Criar objetos socket para comunicação de rede
  2. Implementar um servidor TCP que escuta por conexões
  3. Construir uma aplicação cliente que se conecta a um servidor
  4. Enviar e receber mensagens entre cliente e servidor
  5. Aprimorar seu servidor para lidar com múltiplos clientes simultaneamente
  6. Implementar tratamento de erros robusto tanto no cliente quanto no servidor

Essas habilidades formam a base da programação de rede e podem ser aplicadas para construir uma ampla gama de aplicações em rede, desde programas de bate-papo simples até sistemas distribuídos complexos.

Para continuar sua jornada de aprendizado, considere explorar:

  • Implementação de conexões de socket seguras com SSL/TLS
  • Construção de um protocolo mais complexo para troca de dados estruturados
  • Criação de uma GUI (Interface Gráfica do Usuário) para sua aplicação cliente
  • Uso de I/O assíncrono para maior desempenho com muitas conexões simultâneas

As capacidades de programação de sockets do Python o tornam uma excelente escolha para o desenvolvimento de aplicações de rede, oferecendo um equilíbrio entre simplicidade e poder que poucas outras linguagens podem igualar.