Programação de soquete em C++

Programacao De Soquete Em C



A programação de soquetes tornou-se um assunto importante no campo das redes de computadores. Envolve estabelecer uma conexão entre dois nós, servidor e cliente para se comunicarem sem qualquer interrupção. O servidor atua como ouvinte no canal de comunicação e escuta o cliente em uma porta específica em um endereço IP. Por outro lado, o cliente atua como comunicador no canal de comunicação. O cliente entra em contato com o servidor para criar uma conexão e fazer contato com o servidor. Este artigo tem como objetivo fornecer um guia abrangente e detalhado para programação de soquetes em C++, abordando o básico, apresentando exemplos práticos e fornecendo uma explicação detalhada do código.

Estabelecendo o modelo cliente-servidor

A programação de soquete é o processo que constrói um canal de comunicação entre o servidor e o cliente usando soquetes. No código de exemplo a seguir, o cliente inicia um contato com o servidor e o servidor é configurado para aceitar as conexões do cliente. Vamos entender os segmentos de código do servidor e do cliente, demonstrando seu funcionamento central na comunicação da rede. A seguir está o código do lado do servidor. Vamos ver o código primeiro e depois explicar o código detalhadamente, ponto por ponto.

1. Lado do servidor







O código para o lado do servidor do modelo é fornecido a seguir. Vamos ver o que está acontecendo no código:



#include
#include
#include
#include

usando espaço para nome padrão ;

#define PORTA 8080
#define MAX_BUF_SIZE 1024

interno principal ( ) {
interno ser_socket, cli_socket ;
estrutura sockaddr_in ser_address, cli_address ;
Caracteres bufante [ MAX_BUF_SIZE ] = { 0 } ;

se ( ( ser_socket = tomada ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
erro ( 'Erro na criação do Socket' ) ;
saída ( EXIT_FAILURE ) ;
}

endereço_ser. sin_família = OF_INET ;
endereço_ser. sin_addr . s_addr = INADDR_ANY ;
endereço_ser. porta_sin = toneladas ( PORTA ) ;

se ( vincular ( ser_socket, ( estrutura sockaddr * ) & endereço_ser, tamanho de ( endereço_ser ) ) == - 1 ) {
erro ( 'Falha na vinculação' ) ;
saída ( EXIT_FAILURE ) ;
}

se ( ouvir ( ser_socket, 3 ) == - 1 ) {
erro ( 'Falha ao ouvir' ) ;
saída ( EXIT_FAILURE ) ;
}

corte << 'Servidor escutando na porta' << PORTA << '... \n ' ;

socklen_t cli_address_len = tamanho de ( endereço_cli ) ;
se ( ( cli_socket = aceitar ( ser_socket, ( estrutura sockaddr * ) & endereço_cli, & cli_address_len ) ) == - 1 ) {
erro ( 'Falha ao aceitar' ) ;
saída ( EXIT_FAILURE ) ;
}

ler ( cli_socket, buf, MAX_BUF_SIZE ) ;
corte << 'A mensagem do cliente é:' << bufante << fim ;

enviar ( cli_socket, 'Mensagem do servidor' , Strlen ( 'Mensagem do servidor' ) , 0 ) ;

fechar ( cli_socket ) ;
fechar ( ser_socket ) ;

retornar 0 ;
}

O exemplo dado é o código do lado do servidor do programa C++. Este código funciona para um servidor TCP simples escutar conexões em uma única porta específica. Quando uma conexão for criada com sucesso, o servidor receberá uma mensagem enviada pelo cliente. Depois disso, ele imprime no console e envia uma mensagem de resposta ao cliente. Vamos entender cada linha de código.



O programa começa incluindo as bibliotecas: “iostream” para definições padrão de entrada/saída, “cstring” para funções de manipulação de strings, “unistd.h” para fornecer acesso à API do sistema operacional POSIX e “arpa/inet.h” para realizar as operações da Internet. A instrução “#define PORT 8080” significa que define o número da porta 8080 na qual o servidor irá escutar. O “#define MAX_BUF_SIZE 1024” significa o tamanho máximo do buffer para os dados recebidos que é 1024.





Na função principal, duas variáveis ​​são inicializadas, “ser_socket” e “cli_socket”, para representar o servidor e o cliente, respectivamente. As outras três variáveis ​​​​que são “sockaddr_in”, “ser_address” e “cli_address” do tipo “struct” são inicializadas como estruturas de endereço para o servidor e cliente. Em seguida, é inicializado um buffer denominado “buf” que armazena os dados provenientes do cliente.

A função socket() na condição “if” cria um novo soquete TCP. AF_INET denota IPv4, SOCK_STREAM representa o soquete TCP confiável e orientado à conexão, o último argumento que é 0 é fornecido para selecionar o protocolo TCP padrão, INADDR_ANY aceita as conexões em qualquer endereço IP e htons (PORT) converte o número da porta do ordem de bytes do host para a ordem de bytes da rede.



Como tudo está definido corretamente, o próximo passo é configurar o servidor como lister na porta determinada e aceitar as conexões em qualquer interface de rede. O soquete é fornecido com as informações em “ser_address” pelo método bind(). Imprimimos um erro e encerramos o processo se a ligação falhar. A função accept() abre um novo soquete para a conexão com o cliente, enquanto a função listen() instrui o servidor a aguardar as conexões de entrada. Se a função accept() falhar, a mensagem de erro será impressa e a função será encerrada.

Em seguida, o servidor lê a mensagem do cliente com a função read() no buffer “buf” e a imprime no console. A função send() é usada pelo servidor para enviar uma mensagem em resposta ao cliente. Por último, utilizando close(), o servidor fecha o soquete do cliente, encerrando o programa para que todas as conexões sejam fechadas corretamente e não haja probabilidade de violação de dados.

2. Lado do cliente

Agora, vamos ver o que acontece no modelo cliente:

#include
#include
#include
#include

#define PORTA 8080
#define SERVER_IP '127.0.0.1'

interno principal ( ) {
interno cli_socket ;
estrutura sockaddr_in ser_address ;
const Caracteres * mensagem = 'O cliente está enviando saudações!' ;

se ( ( cli_socket = tomada ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
erro ( 'Erro na criação do soquete' ) ;
saída ( EXIT_FAILURE ) ;
}

endereço_ser. sin_família = OF_INET ;
endereço_ser. porta_sin = toneladas ( PORTA ) ;

se ( inet_pton ( AF_INET, SERVER_IP, & endereço_ser. sin_addr ) <= 0 ) {
erro ( 'Endereço errado' ) ;
saída ( EXIT_FAILURE ) ;
}

se ( conectar ( cli_socket, ( estrutura sockaddr * ) & endereço_ser, tamanho de ( endereço_ser ) ) == - 1 ) {
erro ( 'Falha na conexão' ) ;
saída ( EXIT_FAILURE ) ;
}
enviar ( cli_socket, mensagem, Strlen ( mensagem ) , 0 ) ;

Caracteres bufante [ 1024 ] = { 0 } ;
ler ( cli_socket, buf, tamanho de ( bufante ) ) ;
padrão :: corte << 'Resposta do servidor:' << bufante << padrão :: fim ;

fechar ( cli_socket ) ;
retornar 0 ;
}

Vamos ver cada linha de código para entender como o programa funciona.

As mesmas quatro bibliotecas – iostream, cstring, unistd.h e arpa/inet.h – também estão incluídas no lado do cliente. Um número de porta também é definido junto com o endereço IP do host local 127.0.0.1. A mensagem que deve ser entregue ao servidor é fornecida. O cliente e o servidor precisam estabelecer uma conexão conforme a etapa a seguir:

O “if ((client_socket = soquete (AF_INET, SOCK_STREAM, 0)) == -1);” cria um soquete para IPv4 com um tipo de fluxo e o protocolo padrão TCP. O perror() imprime os detalhes do erro se a função socket() não conseguir estabelecer uma conexão e sair do programa.

O “server_address.sin_port = htons(PORT);” define o número da porta após a conversão para a ordem de bytes da rede. Posteriormente, é fornecida aqui outra mensagem de falha que é o “Endereço errado” que é impressa se houver algo errado com o endereço. Ao localizar o endereço em “ser_address”, o cliente se conectará ao servidor. Se a conexão falhar, os detalhes do erro serão impressos. A função send() irá transferir a mensagem para o servidor, garantindo que ela não contenha nenhum sinalizador.

Para receber e armazenar uma resposta do servidor, um buffer denominado “buf” do tipo “char” é inicializado. A função read() lê a resposta do servidor no buffer. Finalmente, a resposta do servidor é impressa no console. Finalmente, a conexão é fechada usando a instrução close() para encerrar o soquete. A seguir está a saída do programa:

Conclusão

A programação de soquete é uma parte importante da comunicação em rede na ciência da computação. Ele permite o desenvolvimento de aplicações que podem se comunicar pela rede, possibilitando uma ampla gama de possibilidades, desde simples arquiteturas cliente-servidor até sistemas distribuídos estruturados. Quando um soquete é criado em um contexto de programação, o programa deve configurar suas características de terminal, como os protocolos, TCP ou UDP, e o endereço de rede, como o endereço IP e o número da porta. Esses soquetes permitem que os servidores enviem e recebam os dados. Este artigo demonstra um exemplo prático de como funciona o modelo cliente-servidor na programação de soquete.