Elementi di programmazione con interfaccia Socket



Похожие документы
Una semplice applicazione client/server 1

INTERNET DOMAIN SOCKETS (Cap.59)

I Socket. Laboratorio Software M. Grotto R. Farina

Cenni di programmazione distribuita in C++ Mauro Piccolo

Esercitazione [6] Client/Server con Socket

Socket TCP. prima parte

Introduzione alle applicazioni di rete

L interfaccia socket

COMUNICAZIONE TRA PROCESSI REMOTI IN UNIX

Socket TCP. seconda parte

HTTP adaptation layer per generico protocollo di scambio dati

Socket. Nei sistemi operativi moderni i servizi disponibili in rete si basano principalmente sul modello client/server.

Reti (già Reti di Calcolatori )

DATAGRAM SOCKET. Angelastro Sergio Diomede Antonio Viterbo Tommaso

Interazione (TCP) Client-Server con le socket

rsystem Maximiliano Marchesi

Creare una applicazione Winsock di base

J+... J+3 J+2 J+1 K+1 K+2 K+3 K+...

IPC Inter Process Communication

Paradigma client-server

Socket. Nei sistemi operativi moderni i servizi disponibili in rete si basano principalmente sul modello client/server.

Controllo Winsock di Visual Basic

Transmission Control Protocol

I/O su Socket TCP: read()

10.1. Un indirizzo IP viene rappresentato in Java come un'istanza della classe InetAddress.

CORSO DI RETI SSIS. Lezione n.2. 2 Novembre 2005 Laura Ricci

Interprocess Communications - II. Franco Maria Nardini

Socket per TCP: Fondamenti

Laboratorio di Programmazione in Rete

Interazione (TCP) Client-Server con le socket

L uso di Socket UDP. Usiamo le API Winsock incluse in <Winsock.h> A.A. 2005/06. Dott.ssa Valeria Carofiglio

TECNOLOGIE E PROGETTAZIONE DI SISTEMI INFORMATICI E DI TELECOMUNICAZIONI

Reti di Telecomunicazione Lezione 6

Interazione con il DNS Conversioni di Nomi ed Indirizzi

Esercitazione [5] Input/Output su Socket

Esercizi (1-2): da: TCP/IP Sockets in C (Donahoo-Calvert)

Inizializzazione degli Host. BOOTP e DHCP

Reti di Telecomunicazione Lezione 8

Protocolli applicativi: FTP

Esempio 1: stampa locale di file remoto

Networking. Mauro Migliardi Ph. D.

Connessioni di rete. Progetto di reti di Calcolatori e Sistemi Informatici - Stefano Millozzi. PdR_ Stefano Millozzi

Gestione degli indirizzi

API e socket per lo sviluppo di applicazioni Web Based

Luca Mari, Sistemi informativi applicati (reti di calcolatori) appunti delle lezioni. Architetture client/server: applicazioni client

Esercitazione [7] Client/Server con Socket

Socket API per il Multicast

MODELLO CLIENT/SERVER. Gianluca Daino Dipartimento di Ingegneria dell Informazione Università degli Studi di Siena

Introduzione allo sniffing

Esercitazione. Formato di compitini e compiti: domande ed esercizi "closed book" G. Ferrari - Reti di calcolatori.

appunti delle lezioni Architetture client/server: applicazioni client

Altri tipi di connessione

Gestione degli indirizzi

IPC System V. Code di messaggi

Introduzione alla programmazione in C

Opzioni del Socket. Socket Options. Opzioni di Livello Socket. Livello delle Opzioni

Reti di Telecomunicazioni Mobile IP Mobile IP Internet Internet Protocol header IPv4 router host indirizzi IP, DNS URL indirizzo di rete

il trasferimento di file

Corso di Laurea in Ingegneria Informatica. Corso di Reti di Calcolatori I

2.5. L'indirizzo IP identifica il computer di origine, il numero di porta invece identifica il processo di origine.

costruttori e distruttori

API Socket di Berkeley

Esercizio 2. Client e server comunicano attraverso socket TCP

UDP. Livello di Trasporto. Demultiplexing dei Messaggi. Esempio di Demultiplexing

Guida all' uso dei sockets nella programmazione in C

Prova di Esame - Rete Internet (ing. Giovanni Neglia) Lunedì 24 Gennaio 2005, ore 15.00

Nelle reti di calcolatori, le porte (traduzione impropria del termine. port inglese, che in realtà significa porto) sono lo strumento

Università degli Studi di Pisa Dipartimento di Informatica. NAT & Firewalls

Sistemi Operativi: Programmazione di Sistema

Socket & RMI Ingegneria del Software - San Pietro

Maschere di sottorete a lunghezza variabile

Il routing in Internet Exterior Gateway Protocols

DOMOTICA ED EDIFICI INTELLIGENTI UNIVERSITA DI URBINO

Sistemi Operativi (modulo di Informatica II)

P2-11: BOOTP e DHCP (Capitolo 23)

Creare connessioni cifrate con stunnel

Reti di Telecomunicazione Lezione 7

Progettare un Firewall

Транскрипт:

Struttura generale per stream sockets Socket() Well-Known Port Bind() Elementi di programmazione con interfaccia Socket Cenni di programmazione secondo la nuova interfaccia Socket definita nella RFC 2553 Socket() Connect() Write() Read() Close() Connection establishment (3-way handshake) Data (Request) Data (Reply) End-of-File notification Listen() Accept() Blocks until connection received from client Read() Process request Write() Read() 7 Close() Struttura generale per datagram sockets Socket() Sendto() Recvfrom() Close() Well-Known Port Data (Request) Data (Reply) Socket() Bind() Recvfrom() Blocks until datagram received from client Process request Sendto() Funzioni principali (1) socket() Predispone il sistema operativo alla gestione di un nuovo flusso dati creando una struttura in memoria Crea un nuovo socket descriptor con determinate caratteristiche (protocollo di rete, protocollo di trasporto) bind() Collega il socket descriptor precedentemente creato ad una porta specificata Normalmente è utilizzato per un socket di tipo server (anche se esistono casi in cui è utilizzato anche per i client) Il socket non è ancora attivo (non può essere utilzizato per inviare / ricevere dati) listen() Comunica al sistema operativo che deve aspettarsi delle connessioni Crea e gestisce un'apposita coda d'attesa la cui lunghezza è passata come parametro. Una connessione è pronta per essere de-accodata nel momento in cui il 3-way handshake del TCP è terminato correttamente 8 9

Funzioni principali (2) accept() Restituisce un socket descriptor corrispondente alla prima connessione che è stata accodata dalla Listen. La chiamata è bloccnte: se non esistono connessioni in arrivo, il programma si blocca fino a che ne arriva una. Questa funzione crea un nuovo socket descriptor: Il primo (unconnected socket) viene usato per accettare nuove connessioni Il secondo (connected socket) è relativo alla prima connessione accettata Buona prassi è la gestione della nuova connessione attraverso una chiamata di tipo fork() Il processo mantiene un thread in ascolto e un altro al servizio della nuova connessione Funzioni principali (3) connect() Attiva una connessione tra il socket descriptor locale e un socket descriptor remoto. La connessione può essere sia di tipo esplicito (TCP 3-way handshake) oppure implicito (UDP) Questa chiamata viene fatta sempre dal client UDP Questa funzione non è necessaria; è utile per poter utilizzare le primitive send() e recv() anzichè sendto() e recvfrom() Minore overhead di gestione della connessione: ad ogni sendto() il sistema apre il socket, sceglie una porta casuale, invia un datagram e richiude il socket) Necessita di avere una "connessione" aperta per ogni peer close() Chiude un socket descriptor precedentemente creato e ne disalloca le risorse interne Tutti i dati ancora pendenti (ad esempio dati in transito verso il socket chiuso ) vengono persi 10 11 Funzioni di send/receive (1) read(), write() Usabili solo in UNIX Stesso significato e stessa sintassi rispetto al loro utilizzo su un normale file Mancano di alcune peculiarità che sono proprie dei socket Es. leggere i dati senza cancellarli del buffer(msg_peek), etc Tendenzialmente poco usate Funzioni di send/receive (2) send(), recv() Utilizzabili solo su socket connessi Sempre su socket TCP Solo se è stata chiamata la connect() nel caso di socket UDP Permettono alcuni opzioni attraverso l utilizzo dei flags sendto(), recvfrom() Utilizzabili su socket non connessi UDP senza a chiamata connect() Permettono di ricevere/inviare dati da/ad una certa destinazione senza effettuare la connessione a priori Con uno stesso socket permettono di inviare/ricevere dati da molte destinazioni Se utilizzati su socket connessi, i parametri relativi all host remoto vengono ignorati Sono equivalenti a send() e recv() 12 13

socket() Dominio Rappresenta l architettura di rete prescelta TCP/IP, IPX, SNA,.. Tipo Tipologia del socket (connesso, non connesso, etc) Stream, Datagram. Raw Protocollo Nell eventualità che esistano più protocolli che soddisfano le caratteristiche indicate da Dominio e Tipo, questo parametro permette di specificare quale protocollo debba essere scelto Questo parametro è normalmente a zero Il socket descriptor che è stato creato dal sistema operativo socket(): Esempio int SockDescr; /* Socket descriptor */ int family, socktype, protocol; family= AF_INET; /* IP protocol */ socktype= SOCK_STREAM; /* TCP */ protocol= 0; SockDescr = socket(family, socktype, protocol); if (SockDescr == -1) 14 15 bind() struct sockaddr: parametri su cui fare il binding Contiene i parametri (indirizzo, porta) sui quali il server dovrà mettersi in ascolto Indirizzo: può non essere specificato (ci si mette in ascolto su tutti gli indirizzi della macchina) Porta: è obbligatoria per un socket di tipo server struct sockaddr: è una struttura fasulla, necessaria solamente per astrarsi dalla particolare address family in uso Lunghezza della precedente struttura La bind() può operare con architetture di rete diverse (quindi indirizzi con formato diverso) 0 se tutto è OK, -1 in caso di errore bind(): Esempio int ret; /* return value */ struct sockaddr_storage addr; /* address/port on which we */ /* want to create a server */ socklen_t addrlen; /* length of the sockaddr_in */ SockDescr = socket(family, socktype, protocol); addrlen= sizeof(addr); /* now we have to initialize addr (not done here) */ ret= bind(sockdescr, (struct sockaddr *) &addr, addrlen); if (ret == -1) 16 17

listen() Numero massimo di connessioni che possono essere accodate Nel momento in cui il programmatore chiama la accept(), la coda delle connessioni viene decrementata di un unità 0 se tutto è OK, -1 in caso di errore listen(): Esempio int ret; /* return value */ struct sockaddr_storage addr; /* address/port on which we */ /* want to create a server */ socklen_t addrlen; /* length of the sockaddr */ ret= bind(sockdescr, (struct sockaddr *) &addr, addrlen); if (ret == -1) if (listen(sockdescr, MAX_CONNECTIONS) == -1) 18 19 accept() struct sockaddr: parametri della macchina (indirizzo, porta sorgente) che si è connessa a noi Lunghezza della precedente struttura Un nuovo Socket Descriptor relativo alla nuova connessione se tutto è OK, -1 in caso di errore La accept() crea automaticamente un nuovo socket di tipo connesso, necessario per servire la connessione accettata accept(): Esempio int ret; /* return value */ struct sockaddr_storage from; /* address/port of the host */ /* is connecting to us */ socklen_t fromlen; /* length of the sockaddr */ int ChildSock; /* Socket Descriptor of the child */ if (listen(sockdescr, MAX_CONNECTIONS) == -1) ChildSock= accept(sockdescr, (struct sockaddr *) &from, &fromlen); if (ChildSock == -1) 20 21

connect() struct sockaddr: parametri della macchina (indirizzo, porta) con la quale si vuole attivare una connessione Lunghezza della precedente struttura 0 se tutto è OK, -1 in caso di errore connect(): Esempio int ret; /* return value */ struct sockaddr_storage addr; /* address/port of the host */ /* we want to connect to */ socklen_t addrlen; /* length of the sockaddr */ SockDescr = socket(family, socktype, protocol); /* now we have to initialize addr (not done here) */ ret= connect(sockdescr, (struct sockaddr *) &addr, addrlen); if (ret == -1) 22 23 recv() void *buffer Buffer (allocato dall utente) nel quale verranno messi i dati ricevuti int bufferlen Lunghezza del buffer (per evitare buffer overflow) Corrisponde anche alla massima quantità di dati che si vogliono leggere int flags Eventuali modificatori del comportamento della funzione Il numero di bytes letti se tutto è OK, -1 in caso di errori Il numero di dati letti equivale a bufferlen nel caso in cui il numero di dati sia superiore alla disponibilità del buffer recv(): Esempio int AmountRead; /* the number of bytes read */ char Buffer[64000]; /* buffer in which data will be stored */ ChildSock= accept(sockdescr, (struct sockaddr *) &from, &fromlen); if (ChildSock == -1) AmountRead= recv(childsock, Buffer, sizeof(buffer), 0); if (AmountRead == -1) 24 25

send() void *buffer Buffer (allocato dall utente) che deve essere inviato int datatosend Numero di bytes (nel buffer) che devono essere inviati int flags Eventuali modificatori del comportamento della funzione Il numero di bytes inviati se tutto è OK, -1 in caso di errori Il numero di dati inviati può essere inferiore a datatosend nel caso in cui il numero di dati sia superiore alla disponibilità del buffer interno del sistema operativo send(): Esempio int AmountSent; /* the number of bytes sent */ int BytesToSend; /* the number of bytes to send */ char Buffer[64000]; /* buffer in which data will be stored */ ChildSock= accept(sockdescr, (struct sockaddr *) &from, &fromlen); if (ChildSock == -1) /* We suppose Buffer contains only strings */ BytesToSend= strlen(buffer); AmountSent= send(childsock, Buffer, BytesToSend, 0); if (AmountSent == -1) 26 27 close() Indica il socket che si vuole chiudere 0 se tutto è OK, -1 in caso di errore close(): Esempio int ret; /* return value */ struct sockaddr_storage addr; /* address/port of the host */ /* we want to connect to */ socklen_t addrlen; /* length of the sockaddr */ AmountSent= send(childsock, Buffer, BytesToSend, 0); if (AmountSent == -1) ret= close(childsock); if (ret == -1) 28 29

Funzioni introdotte dalla RFC 2553 getaddrinfo() Consente una traduzione di una coppia nomehost/porta in strutture che potranno poi essere utilzizate dai socket successivi È trasparente dal protocollo di rete (IPv4/IPv6) Accetta sia nomi/porte numerici (es 130.192.3.24/80) che letterali (www.polito.it/http) freeaddrinfo() Libera le strutture dati precedentemente allocate dalla getaddrinfo() getnameinfo() Consente di tradurre le variabili di tipo struct sockaddr utilizzate internamente da alcune chiamate socket, in un nomehost/porta di tipo numerico oppure letterale E la speculare della getaddrinfo() Funzioni non supportate in Win32 E previsto il loro abbandono da parte di IETF Sono sostituibili dalle getaddrinfo() e getnameinfo() getipnodebyname() Intendeva sostituire la gethostbyname() Traduce un nome letterale in un insieme di strutture dati per il successivo utilizzo getipnodebyaddr() Intendeva sostituire la gethostbyaddr() Traduce un nome numerico in un insieme di strutture dati per il successivo utilizzo freehostent() Libera le strutture allocate dalle due funzioni precedenti inet_pton(), inet_ntop() Intendevano sostituire le inet_addr() e inet_ntoa() Convertono un indirizzo binario in un indirizzo stringa (stampabile) 30 31 Strutture dati Sono state definite molte strutture dati Storicamente i socket hanno avuto una certa evoluzione Molte informazioni sono presenti in più posti Certe scelte possono apparire, in certi casi, incongruenti Struttura generale : struct addrinfo Mantiene tutti i parametri necessari ad operare Address family, protocollo, indirizzo, porta, flags, nome canonico Definita nella RFC 2553 Strutture di tipo sockaddr Mantengono i parametri più importanti per operare Address family, protocollo, indirizzo, porta Esistono due tipologie di strutture di questo tipo: Strutture reali legate ad un preciso protocollo di rete Strutture astratte indipendenti dal protocollo network Strutture dati astratte Definite per astrarsi dal tipo di indirizzo di rete/porta (e altro) L interfaccia socket è indipendente dal protocollo di livello network struct sockaddr È quella definita storicamente per prima È utilizzata da tutte le principali funzioni (connect(), bind(),) che richiedono per poter operare, informazioni del tipo indirizzo/porta Purtroppo, la sua lunghezza non è sufficiente a mantenere certi indirizzi di rete (la sua lunghezza è pari solamente a 16 bytes) È stata rimpiazzata dalla struct sockaddr_storage struct sockaddr_storage Struttura attualmente in uso È utilizzata per la definizione di variabili che dovranno contenere fondamentalmente indirizzi/porte Non è utilizzata per passare i parametri alle funzioni Per mantenere la compatibilità a livello di API, le funzioni hanno come parametri sempre delle struct sockaddr È necessario effettuare il cast delle variabili di questo tipo in struct sockaddr 32 33

Strutture dati astratte: definizioni struct sockaddr u_short sa_family; /* Address family */ char sa_data[14]; /* Up to 14 bytes of direct address */ }; struct sockaddr_storage short ss_family; /* Address family */ char ss_pad1[_ss_pad1size]; /* 6 byte pad, to make */ /* implementation specific pad up to alignment */ /* field that follows explicit in the data structure */ int64 ss_align; /* Field to force desired structure */ char ss_pad2[_ss_pad2size]; /* 112 byte pad to achieve */ /* the desired size; _SS_MAXSIZE value minus size of */ /* ss_family, ss_pad1, and ss_align fields is 112 */ }; Strutture dati astratte: esempio struct sockaddr_storage from; /* address/port of the host */ /* is connecting to us */ socklen_t fromlen; /* length of the sockaddr */ if (listen(sockdescr, MAX_CONNECTIONS) == -1) /* We cannot know, a priori, if the connecting host is */ /* IPv4 or IPv6: from must be a generic sockaddr_storage */ /* accept() has a struct sockaddr * as second parameter */ /* so we have to cast from into a struct sockaddr */ /* fromlen checks that the size of from is sufficient */ fromlen= sizeof(from); /* Get the size of from */ ChildSock= accept(sockdescr, (struct sockaddr *) &from, &fromlen); 34 35 Strutture dati di tipo sockaddr reali (1) Sono quelle effettivamente utilizzate all interno delle funzioni Le struct sockaddr vengono convertite attraverso appositi cast Funzionamento Quando una funzione si trova a dover riempire una struct sockaddr, la riempie secondo il formato della sockaddr reale relativa a quella address family Le funzioni accettano, oltre al parametro struct sockaddr, anche un parametro indicate la lunghezza effettiva della struttura che è stata definita Necessario per sapere se la variabile originaria è stata allocata della lunghezza effettiva Strutture dati di tipo sockaddr reali (2) Strutture attualmente definite struct sockaddr_in Mantiene i parametri più importanti per il mondo IPv4 Address family, protocollo, indirizzo, porta struct sockaddr_in6 Mantiene i parametri più importanti per il mondo IPv6 Address family, protocollo, indirizzo, porta, flow label, scope 36 37

Strutture di tipo sockaddr_in: definizione struct sockaddr_in6 short sin6_family; /* AF_INET6 */ u_short sin6_port; /* Transport level port number */ u_long sin6_flowinfo; /* IPv6 flow information */ struct in_addr6 sin6_addr; /* IPv6 address */ u_long sin6_scope_id; /* Set of interfaces for scope */ }; struct sockaddr_in short sin_family; /* AF_INET */ u_short sin_port; /* Transport level port number */ struct in_addr sin_addr; /* IPv6 address */ char sin_zero[8]; }; Strutture di tipo sockaddr_in: esempio struct sockaddr_storage from; /* address/port of the host */ /* is connecting to us */ socklen_t fromlen; /* length of the sockaddr */ fromlen= sizeof(from); /* Get the size of from */ ChildSock= accept(sockdescr, (struct sockaddr *) &from, &fromlen); if (from. sa_family == AF_INET) /* This is an IPv4 address */ struct in_addr binip4addr; /* IPv4 address in binary form */ struct sockaddr_in *sockaddr4; /* real struct for IPv4 hosts */ sockaddr4= (sockaddr_in *) &from; /* convert the structure */ binip4addr= sockaddr4->sin_addr; /* assign the IPv4 address */ } 38 39 Struttura generale: struct addrinfo Struttura fondamentale per l utilizzo dei socket Introdotta dalla RFC 2553 Caratteristiche Contiene tutti i parametri necessari a qualunque funzione socket per poter operare Viene riempita automaticamente dalla getaddrinfo() E possibile realizzare una lista linkata di strutture di tipo struct addrinfo Esiste un puntatore next a sè stessa Utilizzata prevalentemente nel caso in cui, ad uno stesso host (identificato come nome letterale, es www.polito.it ) corrispondano più indirizzi diversi In questo caso, la lista linkata permette di scegliere uno tra gli indirizzi identificati Struttura addrinfo: definizione struct addrinfo int ai_flags; /* AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST */ int ai_family; /* AF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for nodename */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; 40 41

Struttura addrinfo: esempio int ClientSock; /* Socket descriptor */ struct addrinfo Hints, *AddrInfo; /* Generic struct addrinfo */ int Ret; /* Generic return value */ /* Reset the content of the Hints variable */ memset(&hints, 0, sizeof(struct addrinfo)); /* Initialize the Hints variable, needed to specify some param */ Hints.ai_family = AF_INET; Hints.ai_socktype = SOCK_STREAM; /* Get the addresses in binary form */ Ret= getaddrinfo( www.polito.it, 80, &Hints, &AddrInfo); ClientSock = socket(addrinfo->ai_family, AddrInfo->ai_socktype, AddrInfo->ai_protocol); /* Connects to the first address returned */ Ret= connect(clientsocket, AddrInfo->ai_addr, AddrInfo->ai_addrlen); freeaddrinfo(addrinfo); 42