You are on page 1of 41

Allan Lima http://allanlima.wordpress.

com
Curso de C/C++ Avanado
Aula 9 Sockets
Allan Lima http://allanlima.wordpress.com
Voc pode:
copiar, distribuir, exibir e executar a obra
criar obras derivadas
fazer uso comercial da obra
Sob as seguintes condies:
Atribuio. Voc deve dar crdito ao autor original, da forma
especificada pelo autor ou licenciante.
Compartilhamento pela mesma Licena. Se voc alterar,
transformar, ou criar outra obra com base nesta, voc somente poder
distribuir a obra resultante sob uma licena idntica a esta.
Para cada novo uso ou distribuio, voc deve deixar claro para outros
os termos da licena desta obra.
Qualquer uma destas condies podem ser renunciadas, desde que
Voc obtenha permisso do autor.
Veja aqui a licena completa
Allan Lima http://allanlima.wordpress.com
Sockets
um mecanismo que os programas
utilizam para se comunicar
Amplamente utilizados em aplicaes dos
mais diversos tipos

Allan Lima http://allanlima.wordpress.com
Tipos de Sockets
Existem dois tipos bsicos sockets:
Stream Sockets
Datagram Sockets
Stream Sockets geralmente utilizam o
protocolo de comunicao TCP
(Transmission Control Protocol)
Datagram Sockets geralmente utilizam o
protocolo de comunicao UDP (User
Datagram Protocol)
Allan Lima http://allanlima.wordpress.com
TCP X UDP
TCP UDP
Orientado conexo No possui conexo
Confivel No Confivel
Entrega ordenada Entrega sem garantias de ordem
Controle de Fluxo Sem controle de fluxo
Allan Lima http://allanlima.wordpress.com
Winsock
a API de sockets do windows
Suporta diversos tipos de protocolos de
transmisso
Sua implementao procedural
No portvel
Allan Lima http://allanlima.wordpress.com
Inicializao
Antes de usarmos as funes da Winsock
devemos inicializa-la chamando a funo
WSAStartup
Allan Lima http://allanlima.wordpress.com
WSAStartup
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);

wVersionRequested verso que ser usada
lpWSAData um ponteiro para a estrutura que ir
guarda as informaes sobre a implementao da
verso usada
Retorna zero em caso de sucesso ou um cdigo de
erro em caso de falha
Allan Lima http://allanlima.wordpress.com
Criando um servidor TCP
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Criando um Socket
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Criando um socket
SOCKET socket(
int af, int type, int protocol
);

af a famlia do endereo
type o tipo do socket
Geralmente AF_INET
protocol o protocolo que ser usado para a
transmisso dos dados
IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP,
IPPROTO_UDP
Retorna o descritor do socket
Allan Lima http://allanlima.wordpress.com
Associando uma porta
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Associando uma porta
int bind(
SOCKET s,
const struct sockaddr* name,
int namelen
);

s o descritor do socket
name contm as informaes sobre o servidor
namelen o tamanho de name em bytes
Retorna zero em caso se sucesso, quando falha
retorna SOCKET_ERROR
Allan Lima http://allanlima.wordpress.com
Um pouco de Histria
Para atrair os programadores do Unix a
API de sockets do windows muito
parecida com ela
Herdando at alguns dos problemas
Por exemplo a struct sockaddr
Allan Lima http://allanlima.wordpress.com
struct sockaddr
struct sockaddr {
// famlia do endereo, AF_xxx
u_short sa_family;
// 14 bytes do endereo do protocolo
char sa_data[14];
};

Pode guardar informao sobre diversos tipos de
sockets
No muito utilizada, mas muitas funes a recebem
como parmetro
Normalmente fazemos um cast para este tipo quando
chamamos alguma funo biblioteca
Allan Lima http://allanlima.wordpress.com
sockaddr_in
struct sockaddr_in { // in de internet
u_short sin_family; // famlia do endereo
u_short sin_port; // porta
struct in_addr sin_addr; // endereo IP
char sin_zero[8]; // completa o tamanho
};

Agrupa os mesmos dados da sockaddr
Criada para resolver as dificuldades de manipulao
do endereo
sin_zero deve ser setado com zeros atravs da funo
memset()
Allan Lima http://allanlima.wordpress.com
struct in_addr
typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} in_addr;

Une as mltiplas formas de se representar um endereo IP
Allan Lima http://allanlima.wordpress.com
Configurando a fila
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Configurando a fila
int listen(
SOCKET s,
int backlog
);

s o descritor do socket
backlog o tamanho mximo da fila de
conexes
Retorna zero em caso de sucesso e
SOCKET_ERROR em caso de falha
Allan Lima http://allanlima.wordpress.com
Recebendo uma conexo
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Recebendo uma conexo
SOCKET accept(
SOCKET s,
struct sockaddr* addr,
int* addrlen
);

s o descritor do socket do servidor
addr ir guardar as informaes do cliente
addrlen ir guardar o tamanho de addr
Retorna o descritor do socket criado para o cliente
Allan Lima http://allanlima.wordpress.com
Enviando e recebendo dados
socket()
bind()
listen()
accept()
recv()/send()
Cria o socket
Associa o socket a uma porta
Configura a lista de conexes
Recebe uma conexo de um cliente
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Recebendo dados
int recv(
SOCKET s, char* buf,
int len, int flags
);
s socket do qual se deseja receber os dados
buf o local onde os bytes lidos sero guardados
len o nmero mximo de bytes a serem lidos
flags influenciam o comportamento da funo
MSG_PEEK, MSG_OOB, MSG_WAITALL
Retorna o nmero de bytes lidos em caso de sucesso
ou SOCKET_ERROR em caso de falha
Allan Lima http://allanlima.wordpress.com
Enviando dados
int send(
SOCKET s, const char* buf,
int len, int flags
);

s socket pelo qual se deseja enviar os dados
buf contm os dados a serem enviados
len o nmero mximo de bytes a serem enviados
flags influenciam o comportamento da funo
MSG_DONTROUTE, MSG_OOB
Retorna o nmero de bytes envidados em caso de
sucesso ou SOCKET_ERROR em caso de falha
Allan Lima http://allanlima.wordpress.com
Exemplo
exemploServidorTCP.cpp
Allan Lima http://allanlima.wordpress.com
Criando um cliente TCP
socket()
connect()
recv()/send()
Cria o socket
Conecta-se ao servidor
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Conectando-se ao servidor
socket()
connect()
recv()/send()
Cria o socket
Conecta-se ao servidor
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Conectando-se ao servidor
int connect(
SOCKET s,
const struct sockaddr* name,
int namelen
);

s descritor do socket
name guarda os dados do servidor com que
a conexo ser estabelecida
namelen o tamanho de name em bytes
Allan Lima http://allanlima.wordpress.com
Exemplo
exemploClienteTCP.cpp
Allan Lima http://allanlima.wordpress.com
Criando um servidor UDP
socket()
bind()
recvfrom()/sendto()
Cria o socket
Associa o socket a uma porta
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Enviando e recebendo dados
socket()
bind()
recvfrom()/sendto()
Cria o socket
Associa o socket a uma porta
Envia e recebe dados
Allan Lima http://allanlima.wordpress.com
Recebendo dados
int recvfrom(
SOCKET s,
char* buf,
int len,
int flags,
struct sockaddr* from,
int* fromlen
);
Allan Lima http://allanlima.wordpress.com
Recebendo dados
s o identificador do socket
buf o local onde os dados recebidos sero
guardardados
len o nmero mximo de bytes que sero lidos
flags influenciam o comportamento da funo
MSG_PEEK, MSG_OOB
from ir guardar os dados do cliente
fromlen o tamanho de from
Retorna o nmero de bytes recebidos em caso
de sucesso ou SOCKET_ERROR em caso de
falha.
Allan Lima http://allanlima.wordpress.com
Enviando dados
int sendto(
SOCKET s,
const char* buf,
int len,
int flags,
const struct sockaddr* to,
int tolen
);
Allan Lima http://allanlima.wordpress.com
Exemplo
exemploServidorUDP.c
Allan Lima http://allanlima.wordpress.com
Criando um cliente UDP
praticamente idntico ao servidor
Exemplo
exemploClienteUDP.cpp
Allan Lima http://allanlima.wordpress.com
Enviando dados
s o identificador do socket
buf contm os dados a serem enviados
len o nmero mximo de bytes que sero
enviados
flags influenciam o comportamento da funo
MSG_DONTROUTE, MSG_OOB
to guarda o endereo do cliente
tolen o tamanho de to
Retorna o nmero de bytes enviado em caso de
sucesso ou SOCKET_ERROR em caso de
falha.
Allan Lima http://allanlima.wordpress.com
Sockets e a MFC
A MFC possui um grande conjunto de
classes que do suporte a sockets
Principais Classes:
CSocket
CSocketFile
CArchive
Estas classes possuem um alto nvel de
abstrao e encapsulam a API s do
Windows
Allan Lima http://allanlima.wordpress.com
Exemplos
exemploServidorTCPSimples.cpp
exemploClienteTCPSimples.cpp
exemploServidorTCPArquivo.cpp
exemploClienteTCPArquivo.cpp
exemploServidorUDP.cpp
exemploClienteUDP.cpp
Allan Lima http://allanlima.wordpress.com
Exerccios
1) Implemente um servidor que envia
arquivos para os seus clientes. O cliente
envia o nome do arquivo para o servidor e
este envia os bytes no arquivo para o
cliente.
Allan Lima http://allanlima.wordpress.com
Referncias
Class Library Reference
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/vclib/html/_mfc_class_library_reference_introduction.asp
Winsocks utilizando Visual C++
http://200.250.4.4/curso-redes-
graduacao/tutorial/socket/tutwsk_c.html
Johnnie's Winsock Tutorial
http://windows.ittoolbox.com/browse.asp?c=WindowsPeerPublis
hing&r=http%3A%2F%2Fwww%2Ehal%2Dpc%2Eorg%2F%7Ejo
hnnie2%2Fwinsock%2Ehtml