TCP_SERVER: socket,bind,listen,accept,(rcv/send),close
TCP_CLIENT: socket,connect,(send/rcv),close
UDP_SERVER: socket,bind,(rcvfrom/sendto),close
UDP_CLIENT: socket,(sendto/rcvfrom),close
/* strutture che utilizzeremo */
struct sockaddr_in {
u_char sin_len;
u_char sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct in_addr {
in_addr_t s_addr;
};
// sockaddr_in è definita in <netinet /in.h>
struct hostent {
char *h_name; // official name of host
char **h_aliases; // alias list
int h_addrtype; // host address type
int h_length; // length of address
char **h_addr_list; // list of addresses from name server
};
// hostent
/* SERVER */
int socket(int family, int type, int protocol)
// family = AF_INET (IPv4), AF_INET6 (IPv6), AF_LOCAL (local Unix)...
// type = SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW (for special IP packets, PING, etc. Must be root)
// protocol = 0 (used for some raw socket options)
// restituisce sockfd
// fare bzero() prima per inizializzare
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
// la sockaddr è in lettura dal SO e può essere riempita con ip e porta altrimenti auto dal SO
// nota : un server può offrire servizi su + indirizzi ip se ha + interfacce di rete
// restituisce 0,-1
int listen(int sockfd, int backlog)
// mette in ascolto la server socket (passiva)
// backlog = num massimo di connessioni in attesa, in genere 5
// non serve nelle connessioni UDP
// restituisce 0,-1
int accept(int sockfd, struct sockaddr *clientaddr, socklen_t *addrlen)
// sockaddr scritto dal SO
// mette in attesa il server e restituisce il NUOVO sockfd che gestisce il client (un po' come welcomeSocket in java)
/* read & write */
int close(int sockfd)
// restituisce o,-1
/* CLIENT */
int socket(int family, int type, int protocol)
// family = AF_INET (IPv4), AF_INET6 (IPv6), AF_LOCAL (local Unix)...
// type = SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW (for special IP packets, PING, etc. Must be root)
// protocol = 0 (used for some raw socket options)
// restituisce sockfd del client per comunicare col server (ancora da associare)
// fare bzero() prima per inizializzare
int connect(int socket fd, const struct sockaddr *serveraddr, socklen_t addrlen)
// sockaddr in lettura dal SO per indirizzare la connessione al server (va impostato prima)
// non ha senso in UDP
// restituisce 0,-1 non socket descriptor
// int bind ...!!! la usa il prof in una esercitazione di un echoClient UDP ???
/* read & write */
int close(int sockfd)
// restituisce o,-1
/* CLIENT & SERVER */
// inizializzazione
struct sockaddr_in myaddr;
bzero(myaddr, sizeof(myaddr) );
oppure memset(&myaddr, 0, sizeof(myaddr) );
// funzioni di IO
int read (int sockfd, char* recvline, int size);
// legge size caratteri dal socket. Se la funzione legge meno dati di quanti richiesti da size, vuol dire che non ci sono dati da leggere.
int readline(int sockfd, char* recvline, int size);
// legge size caratteri dal socket. La funzione si blocca in lettura sul socket fino a quando non riceve una battuta di invio (un carattere di newline '\\n'.
int write(int sockfd, char* line, int size);
// scrive size caratteri nel socket. Se la funzione scrive meno byte di quanti richiesti da size, allora non c'è spazio disponibile nel buffer del socket.
// al posto* delle classiche read() & write() posso utilizzare :
int recv(int sockfd, void *buffer, size_t mbytes, int flags)
int send(int sockfd, void *buffer, size_t mbytes, int flags)
// per UDP invece
int recvfrom(int sockfd, void *buffer, size_t mbytes, int flags, struct sockaddr *from, socklen_t *addrlen)
int sendto(int sockfd, void *buffer, size_t mbytes, int flags, struct sockaddr to, socklen_t addrlen)
/* *hanno in + solo i flags :
MSG_DONTWAIT (this send non-blocking)
MSG_OOB (out of band data, 1 byte sent ahead)
MSG_PEEK (look, but don�t remove)
MSG_WAITALL (don�t give me less than max)
MSG_DONTROUTE (bypass routing table)
*/
struct hostent *gethostbyname(const char *hostname)
// restituisce l'indirizzo ip (in una struttura hostent) associato ad un nome di dominio (www oppure locale)
int gethostname(char *hostname, int bufferlen)
// ritorna il nome dell'host su cui viene lanciata
unsigned long inet_addr(char *addr)
//conversione formato indirizzo da dotted form a numeric (network byte order)
char* inet_ntoa(struct in_addr addr)
// viceversa con addr.s_addr = long int rappesentation
inet_aton("10.1.45.8", &mio_servaddr.sin_addr);
// converte l'indirizzo ip passato come stringa, in una struttura in_addr.
// altre da studiare htons, htons, strtol