Try   HackMD

CS:APP 第 11 章

contributed by < eric88525 >

鳥哥網路介紹,建議先看
video: network programming: Part 1

1. Overview

  • 大部分的網路架構都是 client-server 架構

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • network 是透過有限或是無線相連的系統

    • SAN (system area network)
    • LAN (local area network)
    • WAN (wide area network )
  • internet vs Internet

    • 小寫的 i 代表互相連接的網路
    • Golbal IP Internet 是最有名的 internet

2. Network

lowest level: Ethernet Segment

  • 用於房間或是一層樓
  • each ethernet adapter has 48-bit address(MAC address)
  • host 間傳遞 bit 資料的單位為 frames
  • hub 很懶惰,every host sees every bit






%0



host1

host1



hub

hub



host1--hub




host2

host2



host2--hub

   port



Bridged Ethernet Segment

  • 一堆的 ethernet 可以連成 LAN
  • bridge 知道要把資料傳給哪個 host
  • 用於學校或公司
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

3. internets (lower case)

透過 router 來連接多個 LAN (這些 LAN 未必相同架構)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

internet protocol

  • 提供了 naming scheme (命名規則),如 host address
  • 每個 host 都有他專屬的 address 來識別
  • 定義了傳遞機制,基本單位為 packet
  • packet 含有 header(packet 資訊) 和 payload(資料)

在此架構下的傳遞情況

  • PH: internet packet header
  • FH: LAN frame header

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

4. Global IP Internet

  • 最有名的 internet
  • base on TCP/IP
    • IP (Internet Protocol): provieds basic naming scheme and unrealiable delivery capability of packets from host-to-host
    • UDP (Unreliable datagram protocol): process-to-process 但不穩定
    • TCP (transmission control protocol): 透過 IP 來進行可靠的 process-to-process 傳輸

hardware and software organization of an internet application

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 站在程式的角度
    • Hosts 映射到 32-bit IP address
    • The set of IP addresses is mapped to set of identifiers called internet domain names
    • 不同 host 的 process 可透過 connection 來溝通

IPv4 and IPv6

  • 32 bit-ipv4 不夠用了,因此有 128 bit ipv6 替代
  • IP address 被存在 IP address struct,格式為 network byte order
/* Internet address structure */
struct in_addr {
    uint32_t s_addr; /*network byte order (big-endian)*/
}

Network byte-order conversion functions
l: 32bits
s: 16bit
h: host
n: network

htonl // convert uint32_t from [host] to [network] byte order
htons // convert uint16_t from [host] to [network] byte order
ntohl // convert uint32_t from [network] to [host] byte order
ntohs // convert uint16_t from [network] to [host] byte order

Function of converting between binary IP address and dotted decimal strings
"n": network, "p" presentation

inet_pton:    dotteed deciaml string -> IP address in network byte order
inet_ntop:    IP address in network byte order -> dotteed deciaml string

internet domain name

Q: 要如何將 domain name 對應到 ip 呢?

A: Internet 會維護 IP address <-> domain name 的對應,這些儲存在 huge worldwide distributed database called DNS

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

查詢 DNS 可透過 nslookup 來查找

$ nslookup www.google.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	www.google.com
Address: 74.125.200.105
Name:	www.google.com
Address: 74.125.200.106
Name:	www.google.com
Address: 74.125.200.104
Name:	www.google.com
Address: 74.125.200.99
Name:	www.google.com
Address: 74.125.200.147
Name:	www.google.com
Address: 74.125.200.103
Name:	www.google.com
Address: 2404:6800:4012:2::2004

Internet connections

client 和 server 可透過 connections 互相傳輸 bytes stream , connection 的特性

  • point-to-point
  • Full-duplex: 雙向的
  • Reliable: 資料順序不會變動

A socket is an endpoint of a connection

  • Socket address = IPaddress:port

A port is a 16-bit interger that identifies a process

  • Ephemeral(臨時) port: 當 client 連線時自動決定
  • Well-know port: 提供特殊服務,對應表放在 /etc/services
    • 7/ echo
    • 22/ ssh
    • 25/ smtp

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

5. socket

  • 對於 kernel, sokcet 是連線的終點
  • 對於 application 來說他就是一個 file descriptor 可以 read/write,在 linux 中萬物皆檔案

如果使用 Internet-specific socket,最後要轉形成 (struct sockaddr *)。
當初會這樣設計是希望能有個 interface 能兼容所有種類的 socket address structure。(from book p902)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
The _in suffix is short for internet, not input.

/* 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 byre order */
    unsigned char sin_zero[8]; /* Pad to sizeof (struct sockaddr)*/
};

6. 程式介紹

socket

用於 client 和 server 建立 socket。

/* socket - create an endpoint for communication
 * @domain: protocol
 * @type: communication semantic
 * @protocol: The protocol specifies a particular protocol to be used with the socket.
 * */
int socket(int domain, int type, int protocol);

/* example */
int  clientfd = socket(AD_INET, SOCK_STREAM, 0)

connect

用於 client ,建立和 server 的連線,成功的話 sockfd 就能進行 read / write,

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

bind

  • 用於 server 端
  • The bind function tells the kernel to associate the server’s socket address in my_addr with the socket descriptor sockfd.
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

listen

  • 相較於 client 是主動連線, server 是等待連線。
  • 此函式將 sockfd 從 active socket 轉成具有接受連線能力的 listening socket
  • backlog 為提示 kernel 預計會有多少個連線,要先準備好
#include <sys/socket.h>

/* Returns: 0 if OK, −1 on error */
int listen(int sockfd, int backlog);

open_listenfd

結合了 socket, bind, listen 的 function

#include "csapp.h"

/* Returns: descriptor if OK, −1 on Unix error */
int open_listenfd(int port);

open_clientfd

把 socket 和 connect 包在一起的實做

#include "csapp.h"

/* Returns: descriptor if OK, −1 on Unix error, −2 on DNS error */
int open_clientfd(char *hostname, int port);
/*
 * open_clientfd - open connection to server at <hostname, port> 
 *   and return a socket descriptor ready for reading and writing.
 *   Returns -1 and sets errno on Unix error. 
 *   Returns -2 and sets h_errno on DNS (gethostbyname) error.
 */

typedef struct sockaddr SA;

int open_clientfd(char *hostname, int port) 
{
  int clientfd;
  struct hostent *hp;
  struct sockaddr_in serveraddr;

  if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    return -1; /* check errno for cause of error */

  /* Fill in the server's IP address and port */
  if ((hp = gethostbyname(hostname)) == NULL)
    return -2; /* check h_errno for cause of error */

  bzero((char *) &serveraddr, sizeof(serveraddr));
  serveraddr.sin_family = AF_INET;
  bcopy((char *) hp->h_addr_list[0], 
        (char *) &serveraddr.sin_addr.s_addr,
        hp->h_length);
  serveraddr.sin_port = htons(port);

  /* Establish a connection with the server */
  if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
    return -1;

  return clientfd;
}

accept

Servers wait for connection requests from clients by calling the accept function

#include <sys/socket.h>

/* accept - accept a connection on a socket */
int accept(int sockfd, struct sockaddr *restrict addr,
           socklen_t *restrict addrlen);

Example code

client 端

/*
 * echoclient.c - An echo client
 */
/* $begin echoclientmain */
#include "csapp.h"

int main(int argc, char **argv) 
{
    int clientfd;
    char *host, *port, buf[MAXLINE];
    rio_t rio;

    if (argc != 3) {
	fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
	exit(0);
    }
    host = argv[1];
    port = argv[2];

    clientfd = Open_clientfd(host, port);
    Rio_readinitb(&rio, clientfd);

    while (Fgets(buf, MAXLINE, stdin) != NULL) {
	Rio_writen(clientfd, buf, strlen(buf));
	Rio_readlineb(&rio, buf, MAXLINE);
	Fputs(buf, stdout);
    }
    Close(clientfd); //line:netp:echoclient:close
    exit(0);
}
/* $end echoclientmain */

Server 端

/* 
 * echoserveri.c - An iterative echo server 
 */ 
#include "csapp.h"

/*
 * echo - read and echo text lines until client closes connection
 */
void echo(int connfd) 
{
    size_t n; 
    char buf[MAXLINE]; 
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { //line:netp:echo:eof
	printf("server received %d bytes\n", (int)n);
	Rio_writen(connfd, buf, n);
    }
}

int main(int argc, char **argv) 
{
    int listenfd, connfd;
    socklen_t clientlen;
    struct sockaddr_storage clientaddr;  /* Enough space for any address */  //line:netp:echoserveri:sockaddrstorage
    char client_hostname[MAXLINE], client_port[MAXLINE];

    if (argc != 2) {
	fprintf(stderr, "usage: %s <port>\n", argv[0]);
	exit(0);
    }

    listenfd = Open_listenfd(argv[1]);
    while (1) {
	clientlen = sizeof(struct sockaddr_storage); 
	connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
        Getnameinfo((SA *) &clientaddr, clientlen, client_hostname, MAXLINE, 
                    client_port, MAXLINE, 0);
        printf("Connected to (%s, %s)\n", client_hostname, client_port);
	echo(connfd);
	Close(connfd);
    }
    exit(0);
}

getaddrinfo

Given node and service, which identify an Internet host and a
service, getaddrinfo() returns one or more addrinfo structures,
each of which contains an Internet address that can be specified
in a call to bind(2) or connect(2).

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>


/* Given node and service, which identify an Internet host and a service, 
 * getaddrinfo() returns one or more addrinfo structures, each of which 
 * contains an Internet address that can be specified in a call to 
 * bind(2) or connect(2). */
int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);

void freeaddrinfo(struct addrinfo *res);

const char *gai_strerror(int errcode);

Struct of addrinfo returned by getaddrinfo

struct addrinfo {
    int              ai_flags;
    int              ai_family;
    int              ai_socktype;
    int              ai_protocol;
    socklen_t        ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
};

前面提到 nslookup 可以找 domain 對應許多ip, getaddrinfo 回傳的 linked list 長這樣

getnameinfo 則是相反,將 socket address 轉成對應的 host 和 service

#include <sys/socket.h>
#include <netdb.h>

int getnameinfo(const struct sockaddr *restrict addr, socklen_t addrlen,
                char *restrict host, socklen_t hostlen,
                char *restrict serv, socklen_t servlen, int flags);

Web Servers

  • web client 和 server 使用 text-based application-level protocol HTTP(Hypertext transfer protocol) 溝通。






%0

HTTP protocol


client

client



server

server



client->server


request



server->client


content



web content

  • content is a sequence of bytes with an associated MIME (Multipurpose Internet Mail Extensions) type
  • content 分為 static 和 dynamic content,差別在於有沒有需要處理資料