Punto di contatto fra programmi nella rete.
Struttura che contiene le informazioni necessarie per identificare un processo in una rete.
struct sockaddr_in {
sa_family_t sin_family; // AF_INET
in_port_t sin_port; // Porta di destinazione
struct in_addr sin_addr; // Indirizzo IPv4 di destinazione
unsigned char sin_zero[8]; // Byte riservati
};
struct sockaddr_in6 {
sa_family_t sin6_family; // AF_INET6
in_port_t sin6_port; // Porta di destinazione
uint32_t sin6_flowinfo; // Informazioni di flusso
struct in6_addr sin6_addr; // Indirizzo IPv6 di destinazione
uint32_t sin6_scope_id; // Identificatore di scope
};
Da notare che se si usa un indirizzo IPv6 link local, quelli fe80::/10, è necessario popolare l'indicatore di scope con l'indice dell'interfaccia di rete che si vuole usare. In caso contrario, deve essere impostato a 0.
sockaddr_in
struct sockaddr_in addr4;
socklen_t addrlen = sizeof(addr4);
// memset() per impostare tutti i byte a 0
memset(&addr4, 0, addrlen);
addr4.sin_family = AF_INET;
// htons() per la conversione da host a network byte order
addr4.sin_port = htons(8080);
// inet_addr() per la conversione da stringa a bytes
addr4.sin_addr.s_addr = inet_addr("10.0.0.1");
// oppure
inet_pton(AF_INET, "10.0.0.1", &addr4.sin_addr);
// oppure, per accettare tutte le connessioni al server
addr4.sin_addr.s_addr = INADDR_ANY;
sockaddr_in6
struct sockaddr_in6 addr6;
socklen_t addrlen = sizeof(addr6);
// memset() per impostare tutti i byte a 0
memset(&addr6, 0, addrlen);
addr6.sin6_family = AF_INET6;
// htons() per la conversione da host a network byte order
addr6.sin6_port = htons(8080);
// inet_pton() per la conversione da stringa a bytes
inet_pton(AF_INET6, "2001:db8::1", &addr6.sin6_addr);
// oppure, per accettare tutte le connessioni al server
addr6.sin6_addr = in6addr_any;
// se si sta usando un ip link local
addr6.sin6_scope_id = if_nametoindex("enp0s3"); // o direttamente l'id numerico
getaddrinfo
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // AF_INET o AF_INET6 per IPv4 o IPv6
hints.ai_socktype = SOCK_STREAM; // SOCK_STREAM o SOCK_DGRAM
// Si possono aggiungere varie flag in bitwise or per essere più specifici
hints.ai_flags = AI_PASSIVE; // l'indirizzo verrà usato per una bind
// getaddrinfo() per ottenere una lista di indirizzi
getaddrinfo("10.0.0.1", "8080", &hints, &res);
// res contiene un array di risultati
// res->ai_addr contiene il primo indirizzo
// res->ai_next contiene il puntatore al prossimo risultato
Protocollo di trasporto non orientato alla connessione.
Permette di inviare e ricevere messaggi con pochissimo overhead, senza però fornire garanzie rispetto alla consegna di questi ultimi.
socket()
int socket(int domain, int type, int protocol);
domain
: dominio di comunicazione:
type
: tipo di comunicazione:
protocol
: protocollo di comunicazione:
bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
: descrittore di file della socket su cui fare la bindaddr
: indirizzo a cui fare la bindaddrlen
: dimensione della struttura addr
in bytesrecvfrom()
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
sockfd
: descrittore di file della socket da cui ricevere i datibuf
: buffer in cui salvare i dati ricevutilen
: dimensione del buffer in bytesflags
: flag di ricezione:
src_addr
: indirizzo del mittenteaddrlen
: dimensione della struttura src_addr
in bytessendto()
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
sockfd
: descrittore di file della socket su cui inviare i datibuf
: buffer contenente i dati da inviarelen
: dimensione del buffer in bytesflags
: flag di invio:
dest_addr
: indirizzo del destinatarioaddrlen
: dimensione della struttura dest_addr
in bytesclose()
int close(int sockfd);
sockfd
: descrittore di file della socket da chiudereLoading diagram...
Loading diagram...
Protocollo di trasporto orientato alla connessione.
Offre delle garanzie rispetto alla consegna dei messaggi, gestendo eventuali errori o perdite, ma ha un overhead maggiore rispetto a UDP.
socket()
int socket(int domain, int type, int protocol);
domain
: dominio di comunicazione:
type
: tipo di comunicazione:
protocol
: protocollo di comunicazione:
bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
: descrittore di file della socket su cui fare la bindaddr
: indirizzo a cui fare la bindaddrlen
: dimensione della struttura addr
in byteslisten()
int listen(int sockfd, int backlog);
sockfd
: descrittore di file della socket da cui accettare le connessionibacklog
: numero massimo di connessioni in attesa di essere accettateaccept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd
: descrittore di file della socket da cui accettare le connessioniaddr
: indirizzo del mittenteaddrlen
: dimensione della struttura addr
in bytesconnect()
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd
: descrittore di file della socket che verrà usata in questa connessioneaddr
: indirizzo del destinatarioaddrlen
: dimensione della struttura addr
in bytesrecv()
e send()
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd
: descrittore di file della socket a cui si è connessibuf
: buffer in cui salvare i dati ricevuti/da inviarelen
: dimensione del buffer in bytesflags
: flag di ricezione/invio:
close()
int close(int sockfd);
sockfd
: descrittore di file della socket da chiudereLoading diagram...
Loading diagram...