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_instruct 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_in6struct 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 numericogetaddrinfostruct 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 risultatoProtocollo 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...