This is my note of reading network programming chapter of CSAPP Book
# IP(Internet Protocal) Address
Generally, it is stored(Big endian) in a
struct in_addr
rather than a scalar value.struct in_addr { unsigned int s_addr; /* Network byte order (big-endian) */ };
To convert endianess between local machine word and
in_addr
struct, we need functions#include <netinet/in.h> //Returns: value in network byte order unsigned long int htonl(unsigned long int hostlong); unsigned short int htons(unsigned short int hostshort); //Returns: value in host byte order unsigned long int ntohl(unsigned long int netlong); unsigned short int ntohs(unsigned short int netshort);
Another form is ip address string, which is human readable dotted decimal string like
192.168.100.22
. To convert between Application string and InterNETin_addr
, we have functions:#include <arpa/inet.h> //Returns: 1 if OK, 0 on error int inet_aton(const char *cp, struct in_addr *inp); //Returns: pointer to a dotted-decimal string char *inet_ntoa(struct in_addr in);
- DNS Host entry contains information to domain name, ip address etc together.With following functions, we can search DNS host entry by(string): domain name or dotted decimal ip address.
/* DNS host entry structure */ struct hostent { char *h_name; /* Official domain name of host */ char **h_aliases; /* Null-terminated array of domain names */ int h_addrtype; /* Host address type (AF_INET) */ int h_length; /* Length of an address, in bytes */ char **h_addr_list; /* Null-terminated array of in_addr structs */ };
#include <netdb.h> //Returns: non-NULL pointer if OK, NULL pointer on error with h_errno set struct hostent *gethostbyname(const char *name); //Returns: non-NULL pointer if OK, NULL pointer on error with h_errno set struct hostent *gethostbyaddr(const char *addr, int len, 0);
# Socket Interface
Socket is uniquely identified by ip address(machine) and port number(multiple sockets for same machine). A connection is uniquely identified by the socket addresses of its two endpoints. This pair of socket addresses is known as a socket pair and is denoted by the tuple (cliaddr:cliport, servaddr:servport)
. protocol is also essential to specify a socket interface.
We use struct sockaddr
for general socks address and internet style sockaddr_in
:
/* Generic socket address structure (for connect, bind, and accept) */
struct sockaddr {
unsigned short sa_family; /* Protocol family */
char sa_data[14]; /* Address data. */
};
/* Internet-style socket address structure */
struct sockaddr_in {
unsigned short sin_family; /* Address family (always AF_INET) */
unsigned short sin_port; /* Port number in network byte order */
struct in_addr sin_addr; /* IP address in network byte order */
unsigned char sin_zero[8]; /* Pad to sizeof(struct sockaddr) */
};
The family for internet is always AF_INET
.
# Establish connection between server and client
Headers: <sys/types.h>
and <sys/socket.h>
- Both server and client use
socket
to create socket descriptorint socket(int domain, int type, int protocol);
- Server
- Activate sock by bind socket to a fixed sock_addr
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
- Listen to the socket address
int listen(int sockfd, int backlog);
- Waits until some connection request and then accept.
int accept(int listenfd, struct sockaddr *addr, int *addrlen); //Returns: nonnegative connected descriptor if OK, −1 on error
- The connected file descriptor is different from the istenfd.
- Activate sock by bind socket to a fixed sock_addr
- Client
- Connect to sock address of server
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
- The ephermeral sock_addr=in_addr:port is generated automatically by the kernel
- Connect to sock address of server
- Communication
rio_writen
rio_readlineb
- When server receives EOF, it terminates this connection and start to wait to serve new clients.
# Packed helper function
Pack frequently used open_clientfd
and open_listenfd
.
Comments
comments powered by Disqus