Sockets
Processo
Descritores de Arquivo
2 14 34
Byte Ordering
Como um valor armazenado na memria? Exemplo: 16909060 = 0x01020304
Big-Endian
Endereo n n+1 n+2 n+3 Memria 01 02 03 04 Endereo n n+1 n+2 n+3
Little-Endian
Memria 04 03 02 01
Programao na Internet
Sockets
Estilo: envia/recebe (send/receive) Caracterstica: eficiente
RPC
Chamada remota de procedimento Transparncia e facilidade de programao
Objetos distribudos
Transparncia, facilidade e todos os benefcios da programao
orientada a objetos
Execuo mais lenta Exemplos: DCOM, CORBA, Java RMI, outros
Tipos de sockets
Servio com conexo
Implementa um stream de dados (SOCK_STREAM) Protocolo TCP (tipicamente)
API Sockets
API = Application Program Interface API o elemento de ligao entre a aplicao e um sistema de mais baixo nvel
Consiste de algumas funes bem definidas que podem ser
Sockets Transporte Sistema Operacional (Kernel) Rotinas do S.O. Rede Rotinas do Driver Enlace de Dados Drivers e Hardware Fsica
7
Comandos no Hardware
Aplicao
Sockets Comunicao lgica
Aplicao
Sockets
SO (Kernel)
TCP UDP
...
TCP UDP
...
Fsica
Internet
Comunicao Fsica 8
Bind (Associao)
Um processo servidor precisa associar um socket a um endereo IP e porta para avisar ao sistema operacional que deseja receber dados que chegam ao host.
Sockets
Processos
10 13 20 28 33
Cliente
socket () connect () Processa
Dados (Solicitao)
write ()
Dados (Resposta)
read () close ()
10
Cliente
Processa
Dados (Resposta)
sendto () close ()
recfrom() close()
11
12
#include ... #include <sys/socket.h> int main(int argc, char **argv){ int s; struct sockaddr_in dest; char msg_write[100], msg_read[100]; socket(AF_INET, SOCK_STREAM, 0)); s = socket
CLIENTE
socket () connect () Processa write ()
bzero(&dest, sizeof(dest)); read () dest.sin_family = AF_INET; Com conexo close () dest.sin_port = htons(9999); inet_aton(127.0.0.1, &dest.sin_addr.s_addr); connect(s, (struct sockaddr*)&dest, sizeof(dest)); connect do { scanf("%s",msg_write); /* processamento */ write (s, msg_write, strlen(msg_write)+1); read (s, msg_read, MAXBUF); } while (strcmp(msg_read,"bye")); close close(s); }
13
SERVIDOR
socket () bind () listen () accept () (Bloqueado)
s = socket socket(AF_INET, SOCK_STREAM, 0); bzero(&self, sizeof(self)); self.sin_family = AF_INET; self.sin_port = htons(9999); Com conexo self.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr*)&self, sizeof(self)); bind listen listen(s, 5); while (1) { client_s = accept accept(s,(struct sockaddr*)&client, &addrlen); do { read (client_s, msg_read, MAXBUF); /* processa aqui a mensagem */ write (client_s, msg_read, strlen(msg_read)+1); } while (strcmp(msg_read,"bye")); close close(client_s); }
14
Sockets - Criao
Utiliza-se a chamada de sistema socket():
#include <sys/socket.h> int socket( int domain, int type, int protocol );
Parmetros:
domain o tipo de rede do socket.
AF_INET (Address Family Internet) usado para IPv4 Outros tipos: AF_LOCAL, AF_INET6.
Retorno:
retorna um descritor do socket criado ou 1 em caso de erro.
15
Sockets - Endereos
Endereos IP e portas so armazenados em estruturas do tipo struct sockaddr_in sin_family o tipo do endereo (AF_INET usado para IPv4) sin_port a porta associada ao endereo. sin_addr contm o endereo IP onde se espera a conexo INADDR_ANY indica qualquer IP do host. IP e porta devem ser armazenados em network order (Big-Endian).
Ex: usar a funo
#include <sys/socket.h>
htons(NUMERO)
16
Sockets - Endereos
... int s; char *IP = 200.129.45.123; ushort Porta = 80; struct sockaddr_in dest; s = socket(AF_INET, SOCK_STREAM, 0)); bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(Porta); inet_aton(IP, &dest.sin_addr.s_addr); connect(s,(struct sockaddr*)&dest, sizeof(dest)) ...
17
Sockets - Associao
Utiliza-se a chamada de sistema bind():
#include <sys/socket.h> int bind( int sockfd, struct sockaddr *addr, socklen_t addrlen );
Parmetros:
sockfd o descritor do socket (retornado pela funo
socket()). addr a estrutura com o endereo para ser associado. addrlen o tamanho da estrutura do endereo.
Retorno
A funo retorna 0 (zero) em caso de sucesso ou 1 no caso de um erro Erro comum: EADDRINUSE (Address already in use)
18
Sockets
Traduzindo Endereos IP
A funo inet_aton()
converte um endereo na notao do ponto (1.2.3.4) para o
formato binrio em byte order de rede (como a struct sockaddr_in espera) e retorna 0 (zero) em caso de sucesso.
A funo inet_ntoa()
faz a converso inversa.
19
Sockets
...
20
Sockets
Exemplo:
struct hostent *gethostbyname(); struct hostent *h; struct sockaddr_in *server; struct sockaddr_in sockAddr; h = gethostbyname(argv[1]); if (h == 0) { fprintf(stderr, "%s: unknown host", argv[1]); exit(2); } /* copia o endereo obtido (h->h_addr) para &server.sin_addr */ memcpy(&server->sin_addr, h->h_addr, h->h_length); /* continua ... */
...
21
Sockets TCP
listen()
Para colocar um socket em modo de escuta (servidor) usamos a chamada de sistema listen():
#include <sys/socket.h> int listen( int sockfd, int backlog );
Parmetros:
sockfd o descritor do socket. backlog Nmero mximo de conexes pendentes (fila de
Retorno
O valor de retorno da funo 0 (zero) em caso de sucesso ou 1 caso contrrio.
22
Sockets TCP
accept()
Atende pedidos de conexo pendentes ou fica bloqueada at a chegada de um. #include <sys/socket.h> int accept( int sockfd, struct sockaddr * claddr, socklen_t * len ); Parmetros: sockfd o descritor do socket. claddr a estrutura onde ser guardado o endereo do cliente. len argumento valor/resultado com o tamanho da estrutura do endereo. Retorno um novo descritor (no negativo) em caso de sucesso ou 1 caso contrrio. Cada novo descritor retornado por accept() est associado mesma porta do socket de escuta.
23
Sockets TCP
send()
Parmetros: sockfd o descritor do socket. buffer um ponteiro para os dados a serem enviados. n_bytes quantidade de bytes a serem enviados a partir do ponteiro buffer. flags opes para essa operao. O valor de retorno da funo a quantidade de bytes enviados em caso de sucesso ou 1 caso contrrio.
24
Sockets TCP
recv()
Recebe dados por um descritor conectado, ou bloqueia a execuo at que algum dado chegue ao socket:
#include <sys/socket.h> int recv( int sockfd, void * buffer, size_t n_bytes, int flags );
Parmetros: sockfd o descritor do socket. buffer um ponteiro para a rea de memria onde devem ser armazenados os dados recebidos. n_bytes quantidade mxima de bytes a serem recebidos. flags opes para essa operao. O valor de retorno da funo a quantidade de bytes recebidos em caso de sucesso ou 1 caso contrrio.
25
Sockets UDP
sendto()
#include <sys/socket.h> int sendto( int sockfd, void * buffer, size_t n_bytes, int flags, Parmetros: const socket. sockfd o descritor dostruct sockaddr * to, socklen_t addrlen );
buffer um ponteiro para os dados a serem enviados. n_bytes quantidade de bytes a serem enviados. flags opes para essa operao. to endereo de destino dos dados. addrlen tamanho em bytes do endereo de destino.
O valor de retorno da funo a quantidade de bytes enviados em caso de sucesso ou 1 caso contrrio.
26
Sockets UDP
recvfrom()
Recebe dados por um descritor NO conectado, ou bloqueia a execuo at que algum dado chegue:
#include <sys/socket.h> int recvfrom( int sockfd, void * buffer, size_t n_bytes, int flags, struct sockaddr * from, socklen_t * addrlen );
Parmetros:
sockfd o descritor do socket. buffer um ponteiro para a rea de memria onde devem ser armazenados os dados recebidos. n_bytes quantidade mxima de bytes a serem recebidos. flags opes para essa operao. from ponteiro para a estrutura onde ser escrito o endereo de origem. addrlen argumento valor/resultado com o tamanho do endereo de origem.
O valor de retorno da funo a quantidade de bytes recebidos em caso de sucesso ou 1 caso contrrio.
27
Sockets em Java
Java modernizou a API para trabalhar com sockets O programador no precisa chamar todas as funes, algumas chamadas so automticas Exemplos Socket: equivale a socket + bind do C ServerSocket: equivale a socket + bind + listen do C Sockets so implementados no pacote java.net A transmisso e o envio de dados
So feitos atravs de classes do pacote java.io Semelhante gravao e leitura em arquivos Classes DataInputStream DataOutputStream etc., DataInputStream, DataOutputStream,
28
CLIENTE
public class SimpleJavaClient { public static void main(String[] args) { try { Socket s = new Socket Socket("127.0.0.1", 9999); InputStream i = s.getInputStream(); OutputStream o = s.getOutputStream(); String str; do { byte[] line = new byte[100]; System.in.read(line); o.write write(line); i.read read(line); str = new String(line); System.out.println(str.trim()); } while ( !str.trim().equals("bye") ); close(); s.close } catch (Exception err) { System.err.println(err); } } }
SERVIDOR
public class SimpleJavaServer { public static void main(String[] args) { try { ServerSocket(9999); ServerSocket s = new ServerSocket String str; while (true) { Socket c = s.accept accept(); InputStream i = c.getInputStream(); OutputStream o = c.getOutputStream(); do { byte[] line = new byte[100]; i.read read(line); write(line); o.write str = new String(line); } while ( !str.trim().equals("bye") ); close(); c.close } } catch (Exception err){ System.err.println(err); } } }
Servidores Concorrentes
Muitas vezes necessrio para um servidor lidar com vrios clientes de uma nica vez. Para conseguir isto preciso, de alguma maneira, voltar a aceitar conexes, sem esperar que um cliente seja completamente servido. Isto feito atravs da criao de novas threads ou novos processos. Um servidor, aps o retorno da funo accept(), se divide em dois uma linha de execuo se dedica a atender o cliente, outra volta a esperar por novos pedidos de conexo.
31
32
for( ; ; ) { connfd = accept(listenfd, ...); if ( ( pid = fork() ) == 0 ){ close(listenfd); doit(connfd); close(connfd); exit(0)
close (connfd); }
33
Servidor:
socket = new DatagramSocket(porta); socket.receive( message ); socket.send( message );
34
Servidor:
s = socket(AF_INET, SOCK_DGRAM, 0); bind(s, dest, sizeof(dest)); recvfrom(s, msg, length, flags, fromaddr,
Recursos Disponveis
http://www.javaworld.com/javaworld/jw-12-1996/jw-12-sockets_p.html http://java.sun.com/docs/books/tutorial/networking/index.html http://www.cs.odu.edu/~cs476/fall03/lectures/sockets.htm http://orca.st.usm.edu/~seyfarth/network_pgm/net-6.html Tutoriais Sockets Parte I VII (em portugues):
http://olinux.uol.com.br/artigos/370/1.html http://olinux.uol.com.br/artigos/376/1.html http://olinux.uol.com.br/artigos/383/1.html http://olinux.uol.com.br/artigos/388/1.html http://olinux.uol.com.br/artigos/395/1.html http://olinux.uol.com.br/artigos/398/1.html http://olinux.uol.com.br/artigos/404/1.html
36
37
38
39