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 To convert between Application string and InterNET in_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.
    /* 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 */
    With following functions, we can search DNS host entry by(string): domain name or dotted decimal ip address.
    #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 descriptor
    int 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.
  • 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
  • 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 powered by Disqus