Acesso direto ao conteúdo
Logotipo Dicas-L, por Ricardo Burile
Visite também: Ipok ·  Segurança Linux ·  UnderLinux ·  VivaOLinux ·  LinuxSecurity ·  NoticiasLinux ·  BR-Linux ·  SoftwareLivre.org ·  [mais]   
 

Você está aqui: Home  → Arquivo Dicas-L

 

Lan University - Certificações e Qualificações em TI

Assine a Lista Dicas-L

Receba diariamente por email as dicas
de informática publicadas neste site
Para se descadastrar, clique aqui.

Programando Socket em C++ sem segredo

Colaboração: Alessandro de Oliveira Faria

Data de Publicação: 19 de Dezembro de 2004

As informações contidas neste texto foram baseadas em um artigo escrito por Rob Tougher (<rtougher (a) yahoo com>), publicado na LinuxGazette em Janeiro de 2002. Inclusive os fontes-exemplo são apontados para o link original.

O motivo principal da elaboração deste texto, pois a dificuldade de encontrar algo simples para iniciantes que desejam programar socket em C++.

Sockets são mecanismos usados para a troca de dados entre processos, que podem estar todos em uma máquina local ou em diversas máquinas.

Estou desenvolvendo uma aplicação, na qual diversos clientes em diferentes plataformas e linguagens precisam enviar comandos para o software executar determinadas tarefas.

Este texto contém fundamentos básicos para a criação de aplicações que se comunicam via socket, assim aprenderemos a usar as classes ClientSocket e ServerSocket em C++.

Visão geral sobre comunicação Cliente-Servidor

Antes de partirmos para o código-fonte, vamos entender o funcionamento dos processos Cliente e Servidor:

  • Servidor: Estabiliza o modo ouvinte, aguardando a conexão com um processo cliente
  • Cliente: Cria um socket e tenta conectar-se com um servidor
  • Servidor: Aceita uma conexão cliente
  • Cliente: Envia e recebe dados
  • Servidor: Envia e recebe dados
  • Cliente: Fecha conexão
  • Servidor: Fecha conexão

Este é o funcionamento básico de uma comunicação via socket. Primeiro, o servidor entra em modo escuta, aguardando um processo cliente solicitá-lo.

Um processo cliente ao criar um socket tenta imediatamente conectar-se com o processo SERVER. Assim que a conexão foi estabelecida, ambos os processos começam a trocar dados. Qualquer um dos lados pode encerrar a conexão, fechando o socket.

Executando um simples Server e Client

Vamos agora colocar a mão na massa! Criaremos simples aplicações cliente-servidor suficientes para o aprendizado e para fundamentarmos conceitos de comunicação via socket.

Servidor - Entrando em modo ouvinte

A primeira ação de uma aplicação Server é de entrar em modo escuta por meio de uma porta especificada, por onde a aplicação cliente solicitará a conexão.

Listagem 1: Criando um servidor socket ( parte do fonte simple_server_main.cpp )

  #include "ServerSocket.h"
  #include "SocketException.h"
  #include
  
  int main ( int argc, int argv[] )
  {
  try
  {
  // Criação do server socket na porta 30000
  ServerSocket server ( 30000 );
  
  // insira aqui o restante do código
  
  }
  catch ( SocketException& e )
  {
  // Tratamento de erro
  std::cout << "Exceção foi capturada:" << e.description() << " Finalizando. ";
  }
  
  return 0;
  }

O mais importante na listagem acima é a instanciação da Classe ServerSocket que coloca a aplicação em modo escuta. Se algum método dessa classe falhar, o tratamento de erro invocará o método desctription(), pertencente à classe SocketException.

Cliente - Conectando com o server

O segundo passo é criar uma típica conexão cliente-servidor. A função da aplicação cliente é de tentar se conectar com a aplicação server. Vejamos como efetuar esse procedimento na listagem abaixo:

Listagem 2 : criando um cliente socket ( parte do fonte simple_client_main.cpp )

  #include "ClientSocket.h"
  #include "SocketException.h"
  #include
  #include
  
  int main ( int argc, int argv[] )
  {
  try
  {
  // Criando um client socket e solicitando a conexão na porta 30000 e IP local.
  ClientSocket client_socket ( "localhost", 30000 );
  
  // O restante do código vem aqui.
  
  }
  catch ( SocketException& e )
  {
  std::cout << "Exceção foi capturada:" << e.description() << " ";
  }
  
  return 0;
  }

Resumindo na instanciação da classe ClientSocket, a aplicação tenta conectar no IP e na porta especificada. Se o construtor falhar, o tratamento de erro invoca o método description() conforme mencionado no exemplo do Server.

Server - Aceitando a conexão cliente

O próximo passo é o servidor estabilizar a conexão solicitada pela aplicação Client. Após estabilizar a conexão, um canal de comunicação entre os sockets é criado.

Listagem 3: Estabilizando a conexão com a aplicação cliente (parte do fonte simple_server_main.cpp)

  #include "ServerSocket.h"
  #include "SocketException.h"
  #include
  
  int main ( int argc, int argv[] )
  {
  try
  {
  // Criação do server socket na porta 30000
  ServerSocket server ( 30000 );
  
  while ( true )
  {
  // Aceitando a conexão solicitada
  ServerSocket new_sock;
  server.accept ( new_sock );
  
  // O restante do código vem aqui
  
  }
  }
  catch ( SocketException& e )
  {
  // Tratamento de erro
  std::cout << "Exceção foi capturada:" << e.description() << " Finalizando. ";
  }
  
  return 0;
  }

A conexão é estabelecida justamente na chamada do método accept, que aceita a conexão e preenche em new_sock as informações referentes à conexão atual.

Cliente e Server - Enviando e recebendo dados

Agora que estabelecemos conexão, vamos para a parte de envio e recebimento de dados através do socket.

Umas das grandes características do C++ é a habilidade de sobrecarga de operadores. Usando a sobrecarga de com os operadores << e >>, podemos escrever e ler dados nas classes ClientSocker e ServerSocket.

Listagem 4: Implementações no programa fonte ( simple_server_main.cpp )

  #include "ServerSocket.h"
  #include "SocketException.h"
  #include
  
  int main ( int argc, int argv[] )
  {
  try
  {
  // Criação do server socket na porta 30000
  ServerSocket server ( 30000 );
  
  while ( true )
  {
  // Aceitando a conexão solicitada
  ServerSocket new_sock;
  server.accept ( new_sock );
  
  try
  {
  while ( true )
  {
  std::string data;
  // Recebendo dados
  new_sock >> data;
  // Enviando dados
  new_sock << data;
  }
  catch ( SocketException& ) {}
  }
  catch ( SocketException& e )
  {
  // Tratamento de erro
  std::cout << "Excecão foi capturada:" << e.description() << " Finalizando. ";
  }
  
  return 0;
  }

O new_sock é uma variável que contém todas as informações usadas para a troca de dados com o client. O comando "new_sock >> data;" armazena os dados recebidos na variável data.

A próxima linha é muito parecida, mas executa a tarefa inversa, ou seja, transmite o conteúdo da variável data para o Client.

Resumindo: o programa Server ecoa os dados recebidos pelo Client. Para comprovarmos essa funcionalidade, o fonte abaixo envia uma string ao cliente e aguarda o recebimento do Server, imprimindo o resultado no vídeo.

Listagem 5: implementações no client ( simple_client_main.cpp )

  #include "ClientSocket.h"
  #include "SocketException.h"
  #include
  #include
  
  int main ( int argc, int argv[] )
  {
  try
  {
  // Criando um client socket e solicitando a conexão na porta 30000 e IP local.
  ClientSocket client_socket ( "localhost", 30000 );
  
  std::string reply;
  try
  {
  // Envia a string "Test message" ao server
  client_socket << "Test message.";
  
  // Recebe dados do server
  client_socket >> reply;
  std::cout< catch ( SocketException& ) {}
  
  }
  catch ( SocketException& e )
  {
  std::cout << "Excecão foi capturada:" << e.description() << " ";
  }
  
  return 0;
  }

A aplicação acima, após enviar a string "Test Message" para o Server, aguarda a resposta do Server e ao recebê-la, a string é mostrada no vídeo.

Compilando e testando os fontes

Como mencionei no início desde texto, em www.linuxgazette.com, podemos encontrar todos os fontes citados neste documento. Segue abaixo a relação dos arquivos fontes:

Compilando e Testando

A compilação é simples. Primeiro, salve todos os projeto em um diretório. Logo após, entre com o seguinte comando:

  [root@athlon socket]# make

Este comando compilará todos os arquivos do projeto e criará o binário simple_server e simple_client. Para testá-los, devemos executá-los um em cada terminal (primeiro o server e depois o cliente).

  [root@athlon socket]# cd /mnt/D/linux/fontes/c++/tcp-socket/socket/
  [root@athlon socket]# ./simple_server
  running....
  Test message.
  
  [root@athlon root]# cd /mnt/D/linux/fontes/c++/tcp-socket/socket/
  [root@athlon socket]# ./simple_client
  We received this response from the server:
  "Test message."
  [root@athlon socket]#

O cliente envia a string para o server e aguarda o recebimento dos dados. Após o retorno do Server, a resposta é mostrada no vídeo. Nota-se que o client termina assim que a mensagem é retornada.

Mas o server ficará no modo escuta até que seja interrompido com o CTRL+C.

O Socket é uma maneira simples e eficiente para troca de dados entre processos. Com esse documento, você poderá implementar os recursos sockets em suas aplicações.

Ressalto que este documento é uma versão traduzida/adaptadação do artigo LinuxGazette elaborada por Rob Tougher.

Alessandro de Olivera Faria (Cabelo) <alessandrofaria (a) netitec com br>

 

 

Veja a relação completa dos artigos de Alessandro de Oliveira Faria

Formato PDF
Newsfeed RSS
Formato para impressão
PDF RSS Imprimir

Referências Adicionais

Referências adicionais sobre os assuntos abordados neste site podem ser encontradas em nossa Bibliografia.

Avalie esta dica

  • Currently 3.00/5
  • 1
  • 2
  • 3
  • 4
  • 5

Avaliação: 3.0 /5 (1660 votos)

Opinião dos Leitores

Moacyr
29 Dez 2011, 10:17
Gostei do Tutorial e das referencias quando fui baixar os arquivos vi que links estão quebrados, fiz uma pesquisa na net e encontrei o link para acessar o post original.

http://tldp.org/LDP/LG/issue74/tougher.html
Code Master
10 Set 2011, 00:08
vc é pirata, , copiou as classes, de socket

Linux Socket Programming In C++ , by Rob Tougher

e nem deu referencia..
Leonardo
29 Jun 2011, 17:04
Links quebrados para as referências/includes, deviam ter feito um espelho dos arquivos.
Fernando
06 Abr 2011, 14:15
Leia de novo o artigo que você descobre...
Vitor R.
19 Dez 2010, 15:24
Agradeço pelo tutorial e pelas referências!Como conheço C fica mais fácil entender como funciona. Abraço.
(apesar de o post ser de 6 anos atrás)
Fernando
09 Dez 2010, 14:45
Não gostei, vc não disse de onde que biblioteca vc pegou essas classes >_>
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script


 

Gerenciando Privilégios em Tecnologia da Informação vai ajudá-lo a estabelecer uma noção muito clara dos limites que permitem que seus usuários finais e aplicativos se comuniquem livremente dentro de um ambiente de TI, sem que você tenha de se preocupar c