1 programmazione con socket. 2 cosè un socket? uninterfaccia per la comunicazione tra processi che...

34
1 Programmazione con socket

Upload: calandra-grossi

Post on 01-May-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

1

Programmazione con socket

Page 2: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

2

Cos’è un socket?

• Un’interfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX

• “everything in UNIX is a file”• Tipi di socket:

– Internet Socket– Unix Socket– etc…..

Page 3: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

3

Internet Socket

• Ci sono due tipi principali di Socket:– Stream Socket (SOCK_STREAM)

• Reliable

• Two way connected

• Utilizzano il Transmission Control Protocol (RFC.793)

– Datagram Socket (SOCK_DGRAM)• Not reliable

• Connectionless

• Utilizzano lo User Datagram Protocol (RFC. 768)

Page 4: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

4

Comunicazione Browser/Server Web

Browser Server Web

GET / HTTP\1.1

HTTP\1.1 200 OK

<HTML>…..</HTML>

Page 5: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

5

Come avviene la comunicazione?

Browser

TCP

IP

UDP

TSAP

Server Web

TCP

IP

UDP

TSAPAPI fornite dal S.O.

Il Transport Service Access Point è individuato da un indirizzo di livello 3 (indirizzo IP) ed un indirizzo di livello 4 (port TCP) composto da 16 bit.

Page 6: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

6

socket()

bind()

listen()

accept()

read()

write()

read()

close()

socket()

connect()

write()

read()

close()

Connessione instaurata

Richiesta

Risposta

Stream Socket communication

Page 7: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

7

Strutture C• Socket descriptor: int • Indirizzo di un socket generico:

struct sockaddr { unsigned short sa_family; // address family, AF_xxx char sa_data[14]; // 14 bytes of protocol

address };

• Indirizzo di un Internet Socketstruct sockaddr_in {

short int sin_family; // Address family unsigned short int sin_port; // Port number struct in_addr sin_addr; // Internet address unsigned char sin_zero[8]; // Same size as struct sockaddr

}; struct in_addr {

unsigned long s_addr; // that's a 32-bit long, or 4 bytes };

Page 8: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

8

Conversione Big-Endian / Little-Endian

• Network Byte Order = Big Endian

• Host Byte Order = Big or Little Endian

• Funzioni per la conversionehtons() – “Host to Network Short”

htonl() – “Host to Network Long”

ntohs() – “Network to Host Short”

ntohl() – “Network to Host Long”

Page 9: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

9

Funzioni utili

• in_addr_t inet_addr (const char *str);

restituisce il valore a 32-bit, nell’ordine di rete, ottenuto dalla conversione della stringa puntata da str.

In caso di errore restituisce INADDR_NONE

Page 10: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

10

funzione socket()La prima azione per fare dell’I/O da rete è la chiamata alla funzione

socket() specificando il tipo di protocollo di comunicazione da utilizzare

(TCP, UDP, Unix domain stream protocol per usare le pipe).

#include <sys/socket.h>

int socket (int family, int type, int protocol);

restituisce un descrittore di socket maggiore o uguale a zero, oppure -1

in caso di errore.

Page 11: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

11

funzione socket()• int socket (int family, int type, int protocol);

• family specifica la famiglia di protocolli da utilizzare.PF_INET IPv4 protocolPF_INET6 IPv6 protocolPF_LOCAL Unix domain protocols (ex PF_UNIX)

• type specifica quale tipo di protocollo vogliamo utilizzare all’interno della famiglia di protocolli specificata da family.

SOCK_STREAM socket di tipo stream (connesso affidabile)SOCK_DGRAM socket di tipo datagramSOCK_RAW socket di tipo raw (livello network)

• protocol di solito è settato a 0, tranne che nel caso dei socket raw.

Page 12: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

12

funzione connect()

• La funzione connect() è usata per stabilire una connessione con un server TCP.

#include <sys/socket.h>

int connect (int socketfd, const struct sockaddr *servaddr, int addrlen);

restituisce 0 se la connessione viene stabilita, -1 in caso di errore.

Page 13: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

13

funzione connect()

int connect (int socketfd, const struct sockaddr *servaddr, int addrlen);

• socketfd è un descrittore socket ottenuto da una chiamata alla funzione socket().

• servaddr è un puntatore alla struttura sockaddr_in, e deve specificare l’indirizzo IP e il numero di porta del server al quale connettersi.

• addrlen specifica la dimensione della struttura dati che contiene l’indirizzo del server servaddr, viene di solito assegnata mediante la sizeof(servaddr).

Il client può non specificare il proprio indirizzo IP e la propria porta, chiedendo al sistema operativo di assegnargli una porta TCP qualsiasi e come indirizzo IP l’indirizzo della sua interfaccia di rete. Quindi non è necessaria la chiamata alla bind() prima della connect().

Page 14: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

14

funzione bind()

• La funzione bind() collega al socket un indirizzo locale. Per TCP e UDP ciò significa assegnare un indirizzo IP ed una porta a 16-bit.

#include <sys/socket.h>

int bind (int sockfd, const struct sockaddr *myaddr, int addrlen);

restituisce 0 se tutto OK, -1 in caso di errore.

Page 15: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

15

funzione bind()

int bind (int sockfd, const struct sockaddr *myaddr, int addrlen);

• sockfd è un descrittore ottenuto da una chiamata socket().

• myaddr è un puntatore alla struttura sockaddr_in, e specifica l’eventuale indirizzo IP locale e l’eventuale numero di porta locale a cui il sistema operativo deve collegare il socket.

• addrlen specifica la dimensione della struttura myaddr.

Page 16: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

16

funzione bind()

• Chiamando la bind() si può specificare o no l’indirizzp IP e la porta, assegnando valori ai due campi sin_addr e sin_port della struttura sockaddr_in

• L’assegnazione viene fatta con le istruzioni:

struct sockaddr_in localaddr;

localaddr.sin_addr.s_addr = htonl(INADDR_ANY);

localaddr.sin_port = htons(port_number);

Page 17: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

17

funzione listen()

• La funzione listen è utilizzata solo per implementare un server TCP e esegue due azioni:1) ordina al kernel di far passare il socket dallo stato iniziale CLOSED allo stato LISTEN, e di accettare richieste di inizio connessione per quel socket, mettendole in una coda del kernel.

• 2) specifica al kernel quante richieste di inizio connessione può accodare al massimo per quel socket.

#include <sys/socket.h>int listen (int socketfd, int backlog );

restituisce 0 se tutto OK, -1 in caso di errore.

Page 18: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

18

funzione listen()

int listen (int socketfd, int backlog );

• socketfd è un descrittore ottenuto da una chiamata socket().

• backlog è un intero che specifica quante richieste di inizio connessione il kernel può mantenere in attesa nelle sue code.

Page 19: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

19

funzione accept()

• La funzione accept è chiamata solo dal TCP server e restituisce la prima entry nella coda delle connessioni già completate per quel socket. Se la coda è vuota la accept resta in attesa

.

#include <sys/socket.h>

int accept (int socketfd, struct sockaddr *cli_addr, int *ptraddrlen);

restituisce un descrittore socket >=0 se tutto OK, -1 in caso di errore.

Page 20: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

20

funzione accept()

int accept (int socketfd, struct sockaddr *cli_addr, int *ptraddrlen);

• socketfd è un descrittore ottenuto da una chiamata a socket() sul quale sono state effettuate le chiamate bind() e listen(). Tale listening socket viene utilizzato per accedere alla coda delle connessioni instaurate come si è visto nella funzione listen().

• cli_addr è un puntatore alla struttura sockaddr_in, su cui la funzione accept scrive l’indirizzo IP e il numero di porta del client, con cui è stata instaurata la connessione a cui si riferisce il socket che viene restituito come risultato .

• ptraddrlen è un puntatore alla dimensione della struttura cli_addr che viene restituita.

Page 21: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

21

funzione close()

• La funzione close è utilizzata è utilizzata per chiudere un socket e terminare una connessione TCP.

int close (int socketfd);

restituisce 0 se tutto OK, -1 in caso di errore.

• socketfd è un descrittore di socket.

Page 22: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

22

funzione send()

int send (int socketfd, const void* msg, int len, unsigned int flags);

• La funzione send cerca di scrivere un numero byte pari a len sul file descriptor socketfd, leggendoli dal buffer puntato da msg.Se len è maggiore di zero viene effettuata la scrittura e viene restituito il numero di byte scritti.

Page 23: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

23

funzione recv()

int recv (int socketfd, const void* buf, int len, unsigned int flags);

• La funzione recv cerca di leggere un numero di byte pari a len dal file descriptor socketfd, scrivendoli nel buffer puntato da buf. Se len è maggiore di zero viene effettuata la lettura e viene restituito il numero di byte letti. Se viene restituito zero significa end-of-file (fine stream).

-1 indica che si è verificato un errore.

Page 24: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

24

funzione gethostbyname()

• struct hostent* gethostbyname( char *name );Prende una stringa che contiene il nome dell’host e restituisce una struttura hostent che contiene l’indirizzo (gli indirizzi) IP dell’host.

Struct hostent {char *h_name; //official host namechar **h_aliases; //other aliasesint h_length; //address typechar **h_addr_list; //list of addresses

}

Page 25: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

25

socket()

bind()

recvfrom()

sendto()

close()

socket()

sendto()

recvfrom()

close()

Richiesta

Risposta

Datagram Socket communication

Page 26: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

26

funzione sendto()

int sendto (int socketfd, const void* msg, int len, unsigned int flags, struct sockaddr *to, int *tolen);

• to è un puntatore a una struct sockaddr che contiene l’indirizzo IP e la porta della destinazione.

• tolen può essere inizializzato a sizeof(struct sockaddr)

Page 27: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

27

funzione recvfrom()

• int recvfrom (int socketfd, const void* buf, int len, unsigned int flags, struct sockaddr *from, int * fromlen);

• from è un puntatore a una struct sockaddr che sarà riempita con l’indirizzo IP e la porta della macchina che si è connessa

• fromlen va inizializzato a sizeof(struct sockaddr)

Page 28: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

28

Esempio Client TCP

s = socket(PF_INET, SOCK_STREAM, 0);

indirizzo.sin_family = AF_INET;

indirizzo.sin_port = htons(80);

if ((indirizzo.sin_addr.s_addr = inet_addr("130.251.12.32")) = = INADDR_NONE ) {

perror("inet_addr fallita");

return 1;

}

Page 29: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

29

Esempio Client TCP (2)

if (connect(s,(struct sockaddr *) &indirizzo,sizeof(struct sockaddr_in))!=0) {

perror("connect fallita");

return 1;

}

nw = send(s,messaggio,strlen(messaggio),0);

n=recv(s,buffer,20000,0);

close(s);

Page 30: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

30

Esempio Server TCP…

s = socket(PF_INET,SOCK_STREAM,0);

indirizzo.sin_family = AF_INET;

indirizzo.sin_port = htons(8120);

if (bind(s,&indirizzo,sizeof(struct sockaddr_in))!=0){

perror("bind fallita");

return 1;

}

if (listen(s,3)!=0){

perror("Listen fallita");

return 1;

}

Page 31: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

31

Esempio Server TCP (2)

t=accept(s,NULL,0);

if (t== -1){

perror("Accept fallita");

return 1;

}

lungh=recv(t,buffer,1000,0);

if (lungh < 1 ){

perror("Read fallita");

return 1;

}

Page 32: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

32

Esempio Client UDP

remoteServAddr.sin_family = AF_INET; remoteServAddr.sin_addr.s_addr = inet_addr(“130.251.12.14");

remoteServAddr.sin_port = htons(8000);

sd = socket(AF_INET,SOCK_DGRAM,0);

if(sd<0) { printf("cannot open socket \n"); exit(1); }

msg = “MESSAGGIO";

rc = sendto(sd, msg , strlen(msg)+1, 0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr));

Page 33: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

33

Esempio Server UDP

….

sd=socket(AF_INET, SOCK_DGRAM, 0);

if(sd<0) { printf("cannot open socket \n"); exit(1); }

servAddr.sin_family = AF_INET;

servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

servAddr.sin_port = htons(LOCAL_SERVER_PORT);

rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));

if(rc<0) { printf("cannot bind port number %d \n", LOCAL_SERVER_PORT); exit(1); }

Page 34: 1 Programmazione con socket. 2 Cosè un socket? Uninterfaccia per la comunicazione tra processi che utilizza i file descriptor di UNIX everything in UNIX

34

Esempio Server UDP (2)

while(1) {

memset(msg,0x0,MAX_MSG);

cliLen = sizeof(cliAddr);

n = recvfrom(sd, msg, MAX_MSG, 0, (struct sockaddr *) &cliAddr, &cliLen);

if(n<0) { printf("cannot receive data \n"); continue; }

}