jump to navigation

C Socket Programming in the UNIX environment – part 2 19 novembre 2007

Posted by fripp in C, GNU/Linux, Informatica, Networking, Programmazione, Unix.
Tags: , , , , ,
trackback

Non faccio il riassunto delle puntate precedenti perchè c’è da perdersi!

Inizio di getto, senza alcun preambolo.

La funzione “socket”, descritta nel precedente post, si limita ad allocare a livello kernel le risorse necessarie alla comunicazione, ma non permette ancora la comunicazione tra processi differenti.
Occorre naturalmente un modo per specificare degli indirizzi conformi al protocollo di rete che si vuole utilizzare.
Nell’ambiente UNIX gli indirizzi da usare nelle comunicazioni tramite sockets sono definiti mediante delle particolari strutture C.
La struttura di base (il cui nome ricorrerà spesso) è la struttura “sockaddr”, definita come segue:


#include <sys/socket.h>

struct sockaddr{

	sa_family_t     sa_family;

	char            sa_data[14];

};

sa_familly_t è un typedef che definisce la famiglia di indirizzi a cui deve esser associata la socket.
A questo punto è necessaria una piccola precisazione: lo sviluppatore non ha a che fare con la struttura “sockaddr” direttamente, ma “indirettamente”.
I pratica, le funzioni che prendono in input le strutture che descrivono gli indirizzi (come la bind) prendon come argomenti puntatori a tali strutture; dato che nel C non è previsto alcun meccanismo di overloading delle funzioni, gli sviluppatori avrebbero dovuto definire una funzione per ogni tipo possibile di struttura di indirizzi!
Per risolvere il problema, decisero di definire una struttura di base generica, la sockaddr appunto, e decisero che tutte le funzioni che necessitano di manipolar in qualche modo indirizzi prendessero come argomento un puntatore a tale struttura base.
In questo modo, ogni volta che si deve chiamare una di queste funzioni, nel passare la struttura che descrive l’indirizzo occorre fare un cast a struct sockaddr*.
In pratica, è come se avessero implementato una forma di “ereditarietà” tra le strutture C (adoro l’ereditarietà in C ben riuscita!): la struttura base è la sockaddr e tutte le strutture che “ereditano” da questa hanno in comune il membro di tipo sa_familty_t.
La cosa più naturale sarebbe stata quella di usare dei void* al posto di questa struttura generica, ma l’interfaccia delle socket fu progettata prima della definizione dello standard ANSI C.
Dopo questa breve parentesi, direi che sarebbe meglio ritornar a parlare di cose più “concrete”.
La struttura che descrivi indirizzi IPv4 è la struct sockaddr_in (definita in netinet/in.h), definita come segue:

#include <netinet/in.h>

struct sockaddr_in{
    sa_family_t    sin_family;
    in_port_t         sin_port;
    struct in_addr    sin_addr;
    unsigned char     sin_zero[8];

};

struct in_addr{

    in_addr_t        s_addr;

};

Il “bello” del C è che i typedef sono uno strumento potentissimo per quanto concerne la portabilità del codice, ma sono altrettanto potentissimi nel creare confusione a chi ne fa uso!
Facciamo un po` di ordine: il tipo in_port_t è un unsigned int a 16 bit, il tipo in_addr_t è un unsigned int a 32 bit.
Il campo sin_family della struttura sockaddr_in deve esser inizializzato con l’identificatore della famiglia di indirizzi che si sta usando (in questo caso il suo valore deve esser obbligatoriamente AF_INET); il campo sin_port deve esser inizializzato col numero di porta che s’intende usare, espresso in network byte order; il campo sin_addr contiene l’indirizzo internet, anch’esso espresso in network byte order.Per tutto ciò che concerne il problema degli indirizzi in network byte order vi rimando al prossimo capitolo.Enjoy…………………

Annunci

Commenti»

1. rchrafe - 20 novembre 2007

C Socket Programming in the UNIX environment is an amazing article.

You should do more English papers though fripp 😛

Perhaps we could do great things together.

rchrafe

2. Matt - 28 maggio 2008

ottimo post, mi è stato molto utile, grazie!

3. fripp - 28 maggio 2008

Prego!


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: