Network programming

Client-server model

In this model, an application consists of one server and multiple client. Server manages resources and provide services to client. 1. Client request services 2. Server manipulate resources to satisfy the request 3. Server sends a response to the client

Networks

A network is a hierarchal system of wires and boxes that’s organized by geography proximity. EG: LAN, WAN.

LAN

Lowest Level is LAN. It is consisted of a bunch of hosts connected by wires to a hub. Each host has a 48 bits address. (MAC address) EG:00:16:ea:e3:54:e6.

Host sends each other via frame. Broadcast, so everybody sees every bits.

Next level: internet(lowercase)

internet stands for inter-connected network that connects incompatible LANs together.

internets is usuallyy ad hoc so there is no set topology and we send data via hops across routers.

protocols

Protocols are a set of rules that govern how hosts and routers should communicate. It smoothes out differences between network

Internet Protocols(IP) does: 1. Provide naming scheme such that each host and router can be identified by a unique address. The uniform format is called host address.

  1. Provide deliver mechanisms: Provide the standard unit of transmission called packet that’s consisted of header and payload. Header consists of the packet size, source host address and so on.

The Internet

The Internet can be thought of as a world collection of hosts with the following properities:

  1. Hosts are mapped to 32 bits address.
  2. IP address is mapped to a set of identifier called domain name.
  3. A process on the Internet can communicate with another process via connection.

IP address

IP addresses are stored in IP address struct. The struct contains 1 unsigned int

 /* Internet address structure */
struct in_addr {
    uint32_t  s_addr; /* network byte order (big-endian) */
};

EG:0x8002C2F2

We can convert the hex to human readable dotted decimal form:

0x8002C2F2 = 128.2.194,242

Domain name

The Internet maintains a mapping between IP addresses to domain names called DNS domain name server.

The mapping is not one-to-one. A domain name can map to 1 address, multiple addresses or no address.

The node of the tree represent domain names formed by the path to the root.

Internet connection

Client and server communicates by sending streams of byte over a connection. Each connection is full duplex and point-to-point

A socket is an endpoint of a connection.

A port is a 16 bits that identifies a process: 1. ephemeral port: ports automatically assigned by kernel when client makes a request. 2. Well-known port : Associated with some service provided by the server. EG port 80 for http

Each connection is defined by a socket pair

(client ip: port, server ip: port)

# Socket 

For Linux Kernel, socket is an endpoint of communication. For program, it is just a file with a file descriptor.

A socket address is a struct that contain info about the ip address and port. We have to use a generic socket struct then cast it to different socket address struct since when socket was designed, we can't use generic pointer `void*`.

<img src="http://kedizheng.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-19-at-4.20.59-PM.png" alt="" width="1424" height="490" class="alignnone size-full wp-image-957" />

<img src="http://kedizheng.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-19-at-4.21.51-PM.png" alt="" width="1416" height="616" class="alignnone size-full wp-image-959" />

Above is an IPV4 socket address. For functions to use socket address correctly, we need to first cast `struct sockaddr_in*` to `struct sockaddr *`

## Convert from string representation of sockaddr to struct
we use `getaddrinfo` to do so.


```c
int getaddrinfo(const char *host,            /* Hostname or address */
                const char *service,         /* Port or service name */
                const struct addrinfo *hints,/* Input parameters */
                struct addrinfo **result);   /* Output linked list */

Given host and port number, returns result that points to a linked list of addrinfo structs. In each addrinfo contains a pointer to sockaddr that can be used to bind, accept and listen.

In hints, we specify more control about the connection. Such as IP type and socket types.

The reason getddrinfo returns linked list of addresses structure is because the default behavior is to return 3 structs for 3 different types of connection. 1 for connection, 1 for raw socket and 1 for data gram.

Also a host might have multiple IP address.

It is a linked list because an address for a host might have multiple sockets.

EG: Twitter might have multiple sockets listening?

We can get the host info from struct with

int getnameinfo(const SA *sa, socklen_t salen, /* In: socket addr */
char *host, size_t hostlen,/* Out: host */
char *serv, size_t servlen,/* Out: service */
int flags); /* optional flags */


Socket interface

Creating socket

int socket(int domain, int type, int protocol);

Both client and server uses this function to create socket. EG:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

AF_INET means we use IPV4 and SOCK_STREAM means this is an endpoint of a connection.

Better to use getaddrinfo() to get info for socket since it will be protocol independent.

 struct addrinfo *p = ...;
int clientfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

Connect (by client)

A client establishes connection via

int connect(int clientfd, SA *addr, socklen_t addrlen);

It will block until a connection is successfully established. If successful, we can now read/write via clientfd. The connection is characterized by a pair (x:y,addr.sin_addr:addr.sin_port).

Bind

int bind(int sockfd, SA *addr, socklen_t addrlen);

Where typdef struct sockaddr SA

It will ask the kernel to associate the socket address struct with the socket file descriptor.

After bind, process can read and write from sockfd.

Listen

By default, program will assume a socket opened by socket(...) is an active socket from the client end. Use listen will turn the socket from active socket * to *listening socket.

 int listen(int sockfd, int backlog);

backlog is an hint for the server about how many requests can be queued before rejecting further requests.

Accept

int accept(int listenfd, SA *addr, int *addrlen);

accept(...) will wait for connection request bounded to socket at listenfd, then fill in the client address in addr and the size of socket address length at addrlen.

If successful, it will return a connected descriptor to communicate with the client via UNIX IO.

Connected fd is different from listening socket. A listen socket is created once and will listen for Connection requests. A connected socket is created for the connection and exists only as long as it takes for the server to service the client.

We have such distinct so we can create concurrent server to connect with many client. EG: when a new request comes, we fork a child to handle.

Web server

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax