Escolar Documentos
Profissional Documentos
Cultura Documentos
Decisões de Implementação
Antes de mais nada, para podermos construir programas baseados em
sockets, devemos incluir todos os headers que contêm as declarações e
códigos relativos às funções que iremos usar. São eles:
Iremos usar nossa primeira função: socket(). Esta função é responsável por
criar um socket e retornar uma identificação para ele, a qual denominamos
descritor de socket.
socket = socket(AF_INET,SOCK_STREAM,0);
Esta linha tenta criar um socket voltado à familia internet e que utilizará o
protocolo TCP. Nem sempre um socket poderá ser criado com êxito, e o uso
de um socket inválido causaria vários erros em um programa. Por esta razão,
é fundamental que se verifique a validade de um socket recém-criado antes
de usá-lo. Para fazê-lo, podemos utilizar o valor de retorno da função
socket().
No primeiro modo, fazemos com que o socket fique em modo de espera, isto
é, aguardando conexões. Para tanto, devemos especificar uma porta que
será utilizada e associá-la ao socket. Esta tarefa é realizada através de uma
estrutura denominada sockaddr_in e das funções bind() e listen().
A seguir preenchemos a estrutura sockaddr_in (addr) com os parâmetros
necessários para definir o socket como atuante no modo servidor:
Após configurado, podemos fazer com que o socket aceite conexões que
possam vir a surgir
close(socket);
Maiores detalhes
socket:
descritor do socket;
addr:
ponteiro para uma estrutura sockaddr (ou sockaddr_in);
tamaho_addr:
tamanho, em bytes, da estrutura sockaddr.
backlog:
define o número míximo de conexões pendentes;
socket:
descritor do socket;
addr_opcional:
é um parâmetro opcional que pode ser passado como ZERO. É um ponteiro
para uma estrutura sockaddr que irí retornar informações (endereço e porta)
do computador remoto que requisitou a conexão.
tamanho_addr_opcional:
quando o parâmetro addr_opcional é passado como ZERO, este parâmetro
também se torna opcional. Do contrírio, é um ponteiro para uma variível do
tipo socklen_t (inteiro sem sinal - unsigned long) contendo o tamanho da
estrutura sockaddr.
Caso ocorra algum erro ao aceitar a conexão pendente, accept() retorna -1.
Do contrírio, retorna o descritor para o novo socket.
int send(int socket, const void * dados, int tamanho , int flags);
socket:
descritor do socket;
dados:
dados a serem enviados. Pode-se passar uma string ou variível como valor;
tamanho:
número de bytes a serem enviados;
flags:
valores opcionais normalmente passados como ZERO.
socket:
descritor do socket;
buffer:
buffer no qual serão armazenados os dados recebidos. Geralmente
passamos arrays de chars como parâmetros;
tamanho:
número míximo de bytes que podem ser recebidos;
flags:
valores opcionais normalmente passados como ZERO.
socket:
descritor do socket;
addr:
ponteiro para uma estrutura sockaddr (ou sockaddr_in);
tamaho_addr:
tamanho, em bytes, da estrutura sockaddr.
Uma eventual falha na conexão farí com que a função connect() retorne o
valor -1. Caso a conexão seja feita com sucesso, ZERO é retornado.
Código fonte
Servidor
/*
|
|
---------------------------------------------------------
|
|
| EXECUTAR : $ ./servidor <numero_da_porta> |
|
|
---------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int bytes;
socklen_t length;//para accept() e bind()
/*
A função bind() e responsavel por associar
um endereço e porta locais a um socket.
*/
length = sizeof(struct sockaddr);
if(bind(sockfd, (struct sockaddr *)&server, length) < 0)
{
perror("SERVIDOR ENCERROU");
close(sockfd);
exit(1);
}
/*
A função listen(), coloca-se,
de fato, o socket em modo de espera definindo um míximo
de 1 conexão pendente que deve ser aguardada.
*/
if(listen(sockfd, 2) < 0)
{
perror("SERVIDOR OCULPADO !!!! ");
close(sockfd);
exit(1);
}
printf("\nESPERANDO CONEXAO NA PORTA %s \n\n", argv[1]);
/*
Após configurado, podemos fazer com
que o socket aceite conexoss que possam vir a surgir
*/
new_sockfd = accept(sockfd, (struct sockaddr *)&client,
&length);
if(new_sockfd < 0)
{
perror("SERVIDOR ENCERROU");
close(sockfd);
exit(1);
}
quit = 'N';
while(quit != 'S')
{
bytes = send(new_sockfd, "SERVIDOR FUNCIONANDO!!!", 12,
0);
//ocorreu um erro = -1
if(bytes < 0)
{
perror("SERVIDOR ENCERROU");
close(new_sockfd);
close(sockfd);
exit(1);
}
/*
Sempre quando terminamos de usar um socket,
devemos fechí-lo:
*/
close(new_sockfd);
close(sockfd);
return 0;
}
Cliente
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//conectando-se ao servidor
length = sizeof(struct sockaddr);
if(connect(sockfd, (struct sockaddr *)&server, length) <
0)
{
perror("CLIENTE FALHOU");
close(sockfd);
exit(1);
}
quit = 'N';
while(quit != 'S')
{
bytes = recv(sockfd, recv_buffer, 32, 0);
/*supondo que nao ocorreu um erro acima
ponha o caractere '\0'
*/
recv_buffer[bytes] = 0x00;
/*
enviando string ao servidor.
strlen(send_buffer) pode ser menor que 32
*/
bytes = send(sockfd, send_buffer, strlen(send_buffer),
0);
if(bytes < 0)
{
perror("CLIENTE FALHOU");
close(sockfd);
exit(1);
}
/*
so agora podemos ver a mensagem recebida do servidor
*/
printf("\n RECEBEU : %s\n\n", recv_buffer);
}
return 0;
}
executando servidor
executando cliente
servidor aceitou conexão