Ir para o conteúdo

CCT-UFCA/Ciência da Computação/Sistemas Distribuídos/Programação de Aplicações Cliente/Servidor em uma Rede de Computadores com Sockets e TCP/IP

De Wikiversidade

Conceito de Sockets

[editar | editar código]

Um socket é uma interface para comunicação entre dois processos, seja no mesmo computador ou em máquinas diferentes em uma rede. Ele conecta o aplicativo à camada de transporte (TCP ou UDP).

Os sockets utilizam combinações de um endereço IP e um número de porta para identificar conexões.

  • Tipos de Sockets:
    1. Socket de Fluxo (Stream Socket):
      • Usado com o protocolo TCP para garantir uma conexão confiável.
    2. Socket Datagram (Datagram Socket):
      • Usado com o protocolo UDP para comunicação mais rápida, mas não confiável.
Exemplo:  Ao abrir um navegador, ele usa sockets para estabelecer uma conexão com o servidor web.

Protocolos de Comunicação (TCP/IP, UDP)

[editar | editar código]
  • TCP (Transmission Control Protocol):
    • Protocolo orientado à conexão.
    • Oferece confiabilidade, garantindo que os dados sejam entregues sem perdas e na ordem correta.
    • Divide os dados em pacotes e assegura sua retransmissão se houver falhas.
Exemplo: Navegação na web, e-mails e transferência de arquivos (ex.: HTTP, FTP).
  • UDP (User Datagram Protocol):
    • Protocolo sem conexão.
    • Mais rápido, mas não garante a entrega dos dados nem preserva a ordem.
    • Útil para aplicações onde velocidade é mais importante que confiabilidade (ex.: streaming de vídeo).
Exemplo: Serviços de vídeo em tempo real, chamadas de voz sobre IP (VoIP) e jogos online.

Implementação de Servidores e Clientes Utilizando Sockets

[editar | editar código]

Uma aplicação cliente/servidor com sockets segue um processo estruturado. Abaixo, apresento os passos gerais para cada lado:

Servidor:

  1. Criar socket: Configura o socket usando o tipo e protocolo desejado (TCP/UDP).
  2. Associar o socket a uma porta: Define a porta na qual o servidor escutará conexões.
  3. Ouvir conexões: Fica em modo "escuta" aguardando solicitações.
  4. Aceitar conexões: Estabelece a conexão com o cliente.
  5. Enviar e receber dados: Permite a troca de informações com o cliente.
  6. Fechar o socket: Encerra a conexão.

Cliente:

  1. Criar socket: Configura o socket cliente.
  2. Conectar ao servidor: Estabelece uma conexão com o servidor.
  3. Enviar e receber dados: Realiza a troca de informações.
  4. Fechar o socket: Encerra a conexão.

Exemplo Prático de uma Aplicação Cliente/Servidor

[editar | editar código]

Funcionamento:

  1. O servidor é iniciado e aguarda conexões na porta 8000.
  2. O cliente se conecta ao servidor e envia uma mensagem.
  3. O servidor processa e responde com uma mensagem de confirmação.
  4. Ambos encerram a conexão.
Servidor.py:

import socket


def run_server():
    # create a socket object
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    server_ip = "127.0.0.1"
    port = 8000

    # bind the socket to a specific address and port
    server.bind((server_ip, port))
    # listen for incoming connections
    server.listen(0)
    print(f"Listening on {server_ip}:{port}")

    # accept incoming connections
    client_socket, client_address = server.accept()
    print(f"Accepted connection from {client_address[0]}:{client_address[1]}")

    # receive data from the client
    while True:
        request = client_socket.recv(1024)
        request = request.decode("utf-8") # convert bytes to string
        
        # if we receive "close" from the client, then we break
        # out of the loop and close the conneciton
        if request.lower() == "close":
            # send response to the client which acknowledges that the
            # connection should be closed and break out of the loop
            client_socket.send("closed".encode("utf-8"))
            break

        print(f"Received: {request}")

        response = "accepted".encode("utf-8") # convert string to bytes
        # convert and send accept response to the client
        client_socket.send(response)

    # close connection socket with the client
    client_socket.close()
    print("Connection to client closed")
    # close server socket
    server.close()


run_server()
Cliente.py:

import socket


def run_client():
    # create a socket object
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    server_ip = "127.0.0.1"  # replace with the server's IP address
    server_port = 8000  # replace with the server's port number
    # establish connection with server
    client.connect((server_ip, server_port))

    while True:
        # input message and send it to the server
        msg = input("Enter message: ")
        client.send(msg.encode("utf-8")[:1024])

        # receive message from the server
        response = client.recv(1024)
        response = response.decode("utf-8")

        # if server sent us "closed" in the payload, we break out of the loop and close our socket
        if response.lower() == "closed":
            break

        print(f"Received: {response}")

    # close client socket (connection to the server)
    client.close()
    print("Connection to server closed")

run_client()

Referências

[editar | editar código]
  1. https://linuxsolutions.com.br/sockets-o-que-e-e-como-eles-funcionam/
  2. https://www.treinaweb.com.br/blog/uma-introducao-a-tcp-udp-e-sockets/
  3. https://e-tinet.com/linux/sockets/
  4. https://www.datacamp.com/pt/tutorial/a-complete-guide-to-socket-programming-in-python