美文网首页计算机网络
<< UNIX 网络编程 卷1>> 第1&2章: TCP/IP

<< UNIX 网络编程 卷1>> 第1&2章: TCP/IP

作者: my_passion | 来源:发表于2021-06-11 23:19 被阅读0次

    1 TCP/IP

    C/S 用 TCP 在同一 以太网 上 通信.png OSI 模型
        1  概述
        
            (1) 典型 C/S ( client / server )
    
                [0] 设计 网络应用, 认为 总是由 client 发起 request
                        
                        可 简化 protocol 和 program
    
                [1] web server 程序
                
                    守护程序: 长时间运行
                    
                    `response 网络请求` 时, 才 `发 网络消息`
    
                [2] `web client 程序`: 浏览器
    
                    `与 server 进程 的 通信 总是由 client 进程 发起`
    
            (2) TCP/IP 协议族
    
                `web client 与 server 间 用 
                
                    TCP (Transmission Control Protocol) 通信
                     |
                     |  转而 用 
                     |/
                    IP(Internet Protocol)               通信
                     |
                     |  转而 用 
                     |/
                    以太网协议                           通信
    
            (3)
                    socket: 套接口 // 翻译才更准确 
                1   |   |\
                    |   |   1
                    |   |
                n   |   |   1
                   \|   |
                    sockfd: socket discriptor / 套接字
                        |
                        |/
                        small integer: 标识 套接字
    
                        `socket func 用 sockfd` 去 访问 `具体 socket`
    
            (4) 网络编程 API 
                        |
                        |   之一
                        |/
                    sockets API 
                    
                        是 `应用层 到 传输层/其他层` 的 访问接口
    
                套接字地址结构: 套构
                
        2   简单的 时间获取 C/S program
        
            (1) C 端 
            
                [1] socket():   create TCP 套接字
                    
                    int sockfd = socket(AF_INET, SOCK_STREAM, 0)
             _ _ _ _ _ _ _ _|            |              |
            |                            |/             |/
            |                           网际      字节流
            |   
            |                                   port:13
            |                                   |\  时间获取 server 的
            |                                   |       众所周知 port
            |                                   |
            |                                   |   servaddr.sin_port = htons(13): host to network short ( integer )
            |                                   |   
            |   [2] 指定 对端(Server) 协议族 / port / ipaddr 
            |                           |               |
            |                           |/              |   inet_pton(AF_INET, argv[1], &servaddr.sin_addr)
            |                         地址族           |/                                  |
            |                         AF_INET       ... presentation to number              |
            |                                           把 ASCII 命令行参数 "192.168.*.*"   |
            |                                               转换为 合适格式                 |
            |                                                                               |
            |   [3] connect():  Connect 到 server                                           |
            |                                                                               |
            |           connect(sockfd, (SA *) &servaddr, sizeof(servaddr)                  |
            |_ _ _ _ _ _ _ _ _ _ _ _ |               |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |                                       |
                                                                                            
                [4] read 对端 (Server) 的 Response + 处理
                      |                                 |
                      | 放                              |    如
                      |/                                |/
                      char 数组                       fputs 到 stdout 
                      
                    read() 函数: 每次最多 读 MAXLINE 个 char
                        
                        + TCP 是 `无边界` 字节流
                      
                            => 循环 read(), 直到 read() 返回/读取 char 数 == 0
                            
                    while ( (n = read(sockfd, recvline, MAXLINE) ) > 0) {                   
                        recvline[n] = 0; // 第 n+1  elem 置 null 
                        fputs(recvline, stdout);
                    }
                                                                            
            (2) S 端   
                
                [1] Socket
                    
                    int listenfd = Socket(AF_INET, SOCK_STREAM, 0);
                            |
                            |_ _ _ _ _ _ _ _
                [2] Bind    |               |
                            |               |
                    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr) );
                                                |
                                                |
                                            1] 地址族 AF_INET
                                            2] port: 众所周知 port 
                                            3] 地址: 用 自身 `任一 网络接口地址`
                                                            INADDR_ANY
                
                [3] Listen: 转化 为 `监听套接字`: 以 accept 来自 对端(client) 的 connection 
                        
                    Listen(listenfd, LISTENQ);
                            |
                            |/
                          由 普通套接字 转化为 `监听套接字`
            
                [4]  Accept  + Response
                        |
                        |/
                    1]  阻塞 thread
                              |
                              |  何时被 `唤醒`
                              |/
                            直到 client connection 到达 + 被 OS kernel 接受
    
                    2]  3次握手: 建立连接
    
                    3]  accept 返回 `connfd`
                            
                            connfd = Accept(listenfd, (SA *) NULL, NULL);
                            
                ————————————————————————————————————————————————————————————————————————————
            (3) 3种 套接字          |       作用
                ————————————————————————————————————————————————————————————————————————————
                [1]  普通 sockfd      |   [1] Client 
                                    |       1] socket(AF_INET, SOCK_STREAM, 0)
                                    |       2] connect(sockfd, (SA *) &servaddr
                                    |       3] read(sockfd, pRecv, ...)
                                    |
                                    |   [2] Server
                                    |       1] Socket(AF_INET, SOCK_STREAM, 0)
                                    |
                                    |       2] Bind(listenfd, (SA *) &servaddr, ...)
                                    |                   |
                                    |                   |/
                                    |               普通 sockfd
                                    |                   
                                    |       3] Listen(listenfd, LISTENQ);
                                    |           |                   |
                                    |           |           connnection queue 最大 size   
                                    |           |/
                                    |           普通 sockfd ( listenfd ) 被转换成 
                                    |               监听 sockfd( listenfd)
                ————————————————————————————————————————————————————————————————————————————
                                    |   [2] Server
                                    |
                [2] 监听 sockfd       |       1] Listen(listenfd, LISTENQ);
                                    |
                    listenfd        |           `监听` 来自 client 的 connection -> 放 connnection queue: 最大 size = LISTENQ
                                    |   
                                    |       2] Accept(listenfd, ...)
                ————————————————————————————————————————————————————————————————————————————
                                    |   [2] Server 
                                    |
                [3]  已连接 sockfd |       1] Write(connfd, pBuf, ... )
                                    |
                    connfd          |           `处理 connection`   来自 client 的
                                    |                   
                                    |               `每个 connection 1个 connfd` 
                                    |       
                                    |                   处理 完该 connection 必须 Close: Close(connfd)
                                    |
                                    |       2] Close(connfd)
                                    |
                                    |           close 引发 normal TCP `连接终止 序列`
                                    |               
                                    |               2 个方向 上 都 `发 FIN` + 等 对端确认
                ————————————————————————————————————————————————————————————————————————————
    
        3   本 Server 为 `迭代 Server` 
                |
                |/
                运行快: time + ctime => 用 迭代 Server 合理
                
            ——————————————————————————————————————————————————————————
            [1] 迭代 Server: 只能 同时处理 1 个 connection: 
                            
                    来自 n Clients 的 n 个 connections 
                                
                        connnection queue 
                                    
                            OS kernel 选1个 connnection 给 Accept 返回 
            ——————————————————————————————————————————————————————————
            [2] 并发 Server:   能 同时处理 n 个 connections
    
                    2种方法
                        ——————————————————————————————————————————————
                        1] fork 1 个 子进程: for 每个 Client
                        ——————————————————————————————————————————————
                        2] thread 代替 fork 
            ——————————————————————————————————————————————————————————
            
        4   错误处理: `包裹函数` wrapperFunc
                                    |
                                首字母大写
                                            
            (1) 缩短程序 + 处理前后 可 doOtherThings         
                                    
                [1] 完成 `实际 函数调用`
                [2] check return value
                [3] 出错 时, 终止进程
    
        5   Unix errno 值: global var
    
            [1] E 开头, 通常在 <sys/errno.h>
    
            [2] global -> share -> 多线程 Prob -> Solu
    
        6   OSI 模型
    
            (1) OSI ( open systems interconnection ) 模型
                    
                    ISO 搞的
    
            (2) OSI 与 网际协议族 映射
    
                应 表 会 传           网           数 物
                应       TCP/UDP    IPv4/6   网络设备驱动程序和硬件 
    
                [1] OSI 下两层: 随 OS 提供 / 设备驱动程序 和 网络硬件
    
                    通常, 只 care 数据链路 某些特性:  
                    
                    以太网 MTU 大小 1500 Bytes
    
                [2] 应用层: Web C / S
    
                    对 IP, OSI 上 3 层 几乎 没区别
    
                [3] why so design?
        
                    ————————————————————————————————————————————————————————————————
                                    处理                  |       构成 
                    ————————————————————————————————————————————————————————————————                
                    上 3 层       网络应用 ( FTP / HTTP )     |   user process / 进程
                    ————————————————————————————————————————————————————————————————
                    下 4 层       通信细节                    |   作 OS kernel
                                                            |
                                [1] 发 data                 |
                                                            |
                                [2-1] wait ACK              |
                                [2-2] sort 无序到达 的 data |
                                [2-3] 计算 校验和            |
                    ————————————————————————————————————————————————————————————————
                        分离 `用户进程` 与 `OS kernel`: 
                            
                            `应 / 传 层 间 interface` 是 `构建 API 的 自然位置`             
                    ————————————————————————————————————————————————————————————————                
    
        7   POSIX
    
            Portable Operating System Interface
    

    2 传输层

    TCP/IP 协议 TCP 态转换图 观察分组 并发 Server 之 step1: TCP server 在 port 21 上 被动打开.png step2: client1 `connect 请求`.png step3: 并发 server `fork` 自身的 copy, 让 `子进程` 处理 client1 `connect 请求` step4: client2 `connect 请求`: 同 server + 同 IP地址:port
    线索
        1   TCP UDP 设计 / 实现
    
        2   传输层 协议 TCP UDP 都 转而使用 网际协议 IP
    
        3   UDP vs. TCP
        
            简单 / 不可靠 数据报 协议
    
            复杂 / 可靠 字节流 协议
    
        4   `传输层协议` -> `应用进程`
            
            provide 的 服务
    
            2者各 处理什么
    
        5   `TCP 某些特性 一旦理解, 就很容易 
        
            write 健壮的 + 用 netstat 等 tools debug C/S program`
    
        0   概述
        
            (1) `网络应用` 
    
                [1] tcpdump 
                    
                        用 BPF/DLPI 
                    
                            `不经 传输层`, 直接与 数据链路通信
    
                [2] `Linux` 特殊套接字 `SOCK_PACKET` 
                            
                            访问 `数据链路`
    
                [3] traceroute 
                        
                        用 `IP/ICMP 套接字` 访问 IP/ICMP
    
            (2) 术语
    
                [1] TCP: Transmission Control Protocol(传输控制协议
    
                        给 `用户进程` provide 可靠的 `全双工 字节流`
    
                            TCP 套接字 是 `流套接字(stream socket)`
    
                [2] UDP: User Datagram Protocol (用户数据报协议)
    
                    UDP 套接字 是 `数据报套接字(datagram socket)`
    
                [3] ICMP: Internet Control Message Protocol
    
                    处理 router 与 主机 间 
                        
                        error / control msg
    
                            由 `TCP/IP 网络支持软件` 产生 和 处理
                                    |
                                    | Note
                                    |/
                                而不是 用户进程
    
                [4] IGMP: Internet Group Management Protococl
                    
                    多播
    
                [5] ARP: Address Resolution Protocol
    
                    IPv4 地址 -> MAC/硬件地址
    
                        以太网 / 令牌环网 / FDDI 等 广播网络
    
                            Note
                                `点到点` 网络 `不需要`
    
                [6] RARP: Reverse ...
    
                    MAC 地址 -> IPv4 地址
    
        1   UDP
                    
                    UDP 数据报
                        |
                        |   封装 
                        |/
                    IP 数据报
                    
            `无连接` service
                
                reason: `C 与 S 间 不必存在 长期关系`
                    
                    ————————————————————————
                    1 C + 1 套接字 -> n S
                    ————————————————————————
                    1 S + 1 套接字 <- n C
                    ————————————————————————
                
                =>
                    (1) 3个 不保证
                        
                        不保证 `UDP 数据报`
                    
                            [1] `会 到达` 最终 dst
    
                                要想保证
                                    `应用程序 add 特性: 确认 / 超时 与 重传` 
    
                            [2] `顺序` 跨网络后 不变
    
                            [3] `只到达 1 次`
    
                    (2) Note 
                        
                        数据报 `无法 送给 UDP 套接字` 的 2种 cases
                        
                            [1] 到达 dst + 校验出错
                        
                            [2] 中途丢了
    
                    (3) UDP 数据报 有 length: 随 数据 一起 递送 给 应用进程
                    
                            TCP 无 length 
                                是 字节流
                                
        2   TCP
    
            面向连接: C 与 S 间 connection
    
                C -> S
                    建立连接 -> 交换 data -> 终止连接
    
            =>  
                [1] 可靠 / reliability`
                    
                    ————————————————————————
                    1]  `数据` 的可靠 `递送` 
                    ————————————————————————
                    2]  `故障` 的可靠 `通知`
                    ————————————————————————
                    
                        `而不是` 保证 data `一定被接收`
                        
                        
                            发端 
                                
                                发 data 
    
                                等 对端 确认
    
                                    没收到 确认
                                    
                                        1]  自动重传 + 等更长时间
                                        
                                        2]  数次重传 失败后, 
                                            
                                            通过 `放弃重传 并 中断连接`
                                                
                                                通知 对端 传输失败
    
                [2] 动态 估 RTT
                             |
                            round-trip time 往返时间
    
                                2 种 RTT ( LAN/WAN: ms / s)
                                    
                                    ————————————————————————————
                                    1]  `C/S` 间 RTT
    
                                    2]  `给定连接` RTT 
                                            |
                                            |/
                                        `RTT 受 网络流通 影响`
                                    ————————————————————————————
    
                [3] sequencing
                            
                                 关联
                        1 Byte <- - -> 1 序号
                        |                  |
                        |                  |/
                        |               sequence number
                        |
                        | n(1024) Bytes -> 1 分节 
                        |/
                        分节: TCP 传给 IP 的 DataUint
    
    
                    收端 TCP 据 byteSeq `丢弃 重复 data`
    
                [4] flow control (流量控制) 
                        
                        接收 buf(缓冲区)
                            |
                            |   current 可用 size     
                            |/
                        通知 窗口(advertised window)
    
                            1] tell 对端 maxSendBytesNum
                            
                            2] 动态变化
                                
                                1> 收 data => 变小
                                
                                2> 应用 read from 接收 buf => 变大
    
                [5] full-duplex (全双工)
    
                    `应用` 可同时在 connection 上 收 + 发 
                                                    \  /
                                                    都有 seqNum / windowSize 
    
        3   TCP 连接建立/连接终止
        
            意义
                帮助 理解 connect accept close
            
                用 netstat 调 TCP 应用
    
                IP 数据报 = IP 首 + TCP 首 + 可能的 TCP 选项
                
            (0) 3次握手 / 4次挥手 本质
            
                ——————————————————————————————————————————————————————————————————————————————————
                C/S 两端 都 进行一次 发 + 收 ACK, 来 确保 `自己发的 被对方收到`  
                                     |
                                     |
                                 1] SYN
                                    
                                 2] FIN
                                     
                    => 都是 4 个 分节: 1 / 2 / 3 / 4
                    
                        区别 
                            ——————————————————————————————————————————————————————————————————————
                            1]  连接建立    第2/3 分节 `合并 为1个分节 都由 对端发送  => 3次 握手
                            ——————————————————————————————————————————————————————————————————————
                            2]  连接终止    第2/3 分节 `不能合并` 为1个分节            => 4次 挥手
                                                         |
                                                         |/
                                                    dataRecvQueue 还有 data, 
                                                        FIN 还没取到 
                ——————————————————————————————————————————————————————————————————————————————————
                
                [0] SYN 与 FIN 均 占 1 Byte 序号空间
                
                [1] `SYN/ACK 分节` 中 序号
    
                        1 Byte 序号空间
                          |\
                          | 占
                          |
                        `SYN x = 要发的 `(初始) 序号` 
    
                            => 本端: `要发`     的 `下一序号 = x +1`
                                                        | 
                                                        |   等于
                                                        |
                            => 对端: `期待接收` 的 `下一序号` ACK y
                            
                [2] 
                    
                    FIN x 
                        |
                        |   + 1
                        |/
                    ACK y 
                    
            (1) TCP 连接建立: 3路握手/3个分节`
    
                    [0] S 被动 open
                        |
                        |   准备 accept 外来连接
                        |   
                        |       socket
                        |       bind
                        |       listen
                        |/
                    [1] C 发起 `主动 open`
                        |
                         - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
                                                                                          |
                            connect                                                       |
                                                                                          |
                                =>  client TCP `发 SYN(同步)` 分节 -> (通常) 不带 data     |
                                                    |                                     |
                                                    | tell 对端 S - - - - - - - - - - - - -
                                                    |/                      |
                                            自己要发 data 的 `(初始)序号`   |
                                                                            |
                           - - - - - - - - - - - - - - - - - - - - - - - - -                                                    |
                          |                                                 
                    [2] 对端 S 回 ACK + 发 SYN
                        |
                        |
                    [3] C 回 ACK
                    ————————————————————————————————————————————————————————————————————
                    
            (2) TCP 连接 终止: 4次挥手/4个分节`
    
                [1] 本端 `主动 close`
    
                    `close 直接 被 ( 应用进程 ) 调用`
                    
                                    |
                                    | =>
                                    |/
                            TCP `发 FIN` 
                                    |
                                    | tell 对端
                                    |/
                                自己 data 已发完                     
    
                [2] 对端 收到 FIN 后 `被动关闭`
    
                    read 返回 0:  no longer read
    
                        => `FIN 的 接收 作 `end-of-file`(文件结束符) 放 `应用进程` 的 `dataRecvQueue` 尾 +  `回 ACK`
                                            |                               |
                                            |                               |
                                            |- - - - - - - - - - - - - - - -
                                            some time later [3] `取到 eof == 收到 FIN` 
                                                    
                                                                    =>  `close`
                                                                            |
                                                                            | =>
                                                                            |/
                                                                        `发 FIN`
                                                                            |
                                                                            |/
                                                                [4] 本端 回 ACK
    
            (3) Note
            
                [1] 发 FIN 的 另 2种 case
    
                    `close 间接 被 ( 运行库 ) 调用`
                    
                        `进程  终止` => `所有 connfd` 上都调 `close` =>  相应 connection 发 FIN
    
                            1] 自愿
                                
                                1>  调 exit 
                                
                                2>  从 main 返回
                            
                            2] 非自愿
                                
                                收到 终止本进程 的 signal 
                [2] 2种 异常终止
    
                    1] step1 的 FIN 随 data 发送
    
                    2] step2/3 中 ACK/FIN 合为 1个 分节
    
                [3] half-close
    
                    step2/3 间, `被动关闭端` 仍发
    
                        =>  shutdown 相关
                        
        4   TIME_WAIT 状态
    
                [1] `主动 close 端` 
                        
                        在 TIME_WAIT 状态 
                            
                            持续时间 = 2MSL
                                        |
                                        |   maximum segment lifetime
                                        |            |
                                        |            |  指   
                                        |           IP 数据报
                                        |/          
                                        MSL
    
                                            上限 255
                                                `IP 数据报: hop limit 字段 = 8位
    
                [2] `迷途 重复分组 / lost duplicate`
                            |
                            |   如 
                            |/
                            TCP 分节
    
                    原因: `路由 异常`
                            |
                            |    
                            |/
                            修复: 期间 `路由循环(router1/2 把分组 相互传来传去)`
    
                [3] TIME_WAIT 状态 存在的理由?
    
                    1]  实现 可靠的 连接终止
    
                    2]  保证 每建立1个 新 connection 
                        
                            来自该连接 的 
                                
                                `先前化身 的 老的重复分组 已消逝`
    
        5   TCP 端口号 与 并发服务器
    
            `单宿(单 IP 地址) clients 主机` 上 起 `2 个 client` 
            
                通过 `不同 TCP 端口 均 连接到` 
                    
                    1个 `多宿 server` 的 `同一 IP 地址:port` 上
        
                        并发 server
    
            (1) TCP server 在 port 21 上 被动打开
    
            (2) client1 `connect 请求`
    
            (3) 并发 server `fork` 自身的 copy, 
                
                    让 `子进程` 处理 client1 `connect 请求`
    
            (4) client2 `connect 请求`: 同 server + 同 IP地址:port
    
                    TCP 必须查看 `两端 socketPair = 4 个元素` 
                        
                        才能确定让 `哪个 子进程 去处理 哪个 connection` 
    
        6   TCP 选项/状态转移图/观察分组
        
            (1) TCP 选项
    
                    1SYN -> n TCP 选项 ( 在 `TCP 首部` )
    
                    [1] `MSS: maximum segment size 最大分节大小`
    
                            => `发端 TCP` 用 `收端 MSS` 作 `发送分节 最大大小`
                
                    [2] `窗口规模: 通知窗口 ( 字段 占 16 位 )` 要 `左移 的 位数 (0-14)` 
                            |
                            |/
                            变大 
                        
                                TCP 两端都支持该选项, 才能使用之
                
                    [3] `时间戳`
    
            (2) `TCP 态转换图`
    
                状态转移图 并不难理解, 可分 3 部分 + 1 key
    
                `part1: 沿 粗实线 / Client 正常状态转换`
    
                    CLOSED
                    -> 应用: 主动打开 -> 导致 -> 发: SYN
                    -> SYN_SENT
                    -> 收: ACK + SYN -> 导致-> 发: ACK
                    -> ESTABLISHED
                    -> 应用: 关闭 -> 导致 -> 发: FIN
                    -> FIN_WAIT_1
                    -> 收: ACK -> 发: <无>
                    -> FIN_WAIT_2
                    -> 收: FIN -> 导致 -> 发 ACK
                    -> TIME_WAIT 
                    -> 2 MSL 超时
                    -> CLOSED
    
                `part2: 沿 粗虚线 Server 正常状态转换`
    
                    CLOSED
                    -> 应用: 被动打开 -> 导致 -> 发: <无>
                    -> LISTEN
                    -> 收: SYN -> 导致-> 发: ACK + SYN
                    -> SYN_RCVD
                    -> 收: ACK -> 导致 -> 发: <无>
                    -> ESTABLISHED
                    -> 收: FIN -> 导致 -> 发: ACK
                    -> CLOSE_WAIT
                    -> 应用: 关闭 -> 导致 -> 发: FIN
                    -> LASK_ACK
                    -> 收: ACK -> 导致 -> 发: <无>
                    -> CLOSED
    
                `part3: other 转换`
    
                    Client 端:
                    1) 到 同时打开
                    2) 到 同时关闭
                    3) 同时关闭 到 TIME_WAIT
                    4) FIN_WAIT1 接收 ACK + SYN
                    5) SYN_SENT -> 应用关闭
    
                    Server 端:
                    收 RST
    
    
                [1] SYN_SENT
    
                    -> 1) 应用: 关闭 或 超时 
                    -> CLOSED
    
                    -> 2) 收: ACK + SYN -> 导致-> 发: ACK
                    -> ESTABLISHED
    
                    -> 3) 收: SYN ( `同时打开` ) -> 导致 -> 发: ACK 
                    -> SYN_RCVD
    
                [2] FIN_WAIT_1
    
                    -> 1) 收: ACK -> 发: 无
                    -> FIN_WAIT_2
                    -> 收: FIN -> 导致 -> 发 ACK
    
                    -> 2) 收: ACK + SYN -> 导致 -> 发: ACK
    
                    -> 3) 收: FIN ( `同时关闭` ) -> 导致 -> 发: ACK
                    -> CLOSING
    
                    -> TIME_WAIT 
    
    
                key: `start 状态 处于 C 端 还是 S 端`
                        
                        -> `应用进程` 可能 `发起 什么操作` or `收到 什么分节` 
                            
                            -> `导致 发送 什么` & `转换到 什么状态`
    
    
                        note:
                        (1) TCP 为 connection 定义 11 种状态
    
                        netstat 可 显示 11 种 状态名
                        用于 debug C/S 程序时, 监视 TCP 状态变化
    
                        (2) ( 应用 ) 进程
    
                        TCP OS 内核进程 之上 应用层 用户进程
    
                        (3) TCP 规定 如何 基于 
                        `当前状态 + 应用进程 发起的操作 / 所接收的分节` 
                        从 一个状态 转换到 另一状态
    
                        //eg
                        某 `应用进程` 在 CLOSED 状态 下 `执行` 
                        主动打开 
                        -> TCP `发 SYN` 
                        -> 新状态 为 SYN_SENT
                        -> 该 TCP `收 ACK + SYN`
                        -> 该 TCP 将 `发 ACK`, 且 新状态 为 ESTABLISH
    
                        (4) 细实线 中 除 server 接收 RST 之外, 其余 均为 
                        `client 端 操作`:
                        应用 (应用进程 发起操作)
                        接收
                        发送
    
                        (5) 应用(进程发起操作) / 接收 -> 导致 -> 发送
    
            (3) 观察分组
    
                展示 C/ S 端 经历的 TCP 状态
    
                C / S 通告的 MSS 可不同, 536 / 1460 Bytes
                1460(以太网 IPv4 典型值)
    
    
                `捎带 piggybacking`
    
                    S 对 C 请求 的 `ACK 随 应答 发送`
    
                    6   第 3 次握手 失败`
    
                        `server 会定时 重发 ACK + SYN`, 
                        重传 指定次数 后, 仍未 收到 ACK
                        一段时间后, `server 自动关闭 该 conn`
    
                            此时
    
                            `client 认为 该 conn 已建立` -> `C 向 S 写 数据`, S 回 `RST`
    
                                `RST: Reset 异常关闭连接`
    
        7   端口号
    
            `TCP/UDP/SCTP 协议` 都用 `端口号(port number)` 来 `区分 多进程 (的 server/clients 端)`
    
    
                2类/3种 端口:
    
    
            (1) 标识 server
    
                可能的话, `相同的端口号` 分给 `TCP/UDP` 的 `同一给定服务`
    
                    端口号`80 / 6000-6063` 都被赋予 TCP及UDP 的 `web / X Window server`
    
                    FTP server: 21
    
                1) `众所周知端口(well-known port): 0-1023`
    
                    即 BSD `保留端口`
    
                    使用 `reserved port` 的 `server` 必须 以 `超级用户特权` 启动
    
                2) registered port: 1024-49151
    
            (2) 标识 clients
    
                临时端口(ephemeral port)
                    (3/4)*65536 = 49152-65535
    
                1) client 使用, 短期存活 
        
                2) 由 传输层协议 自动赋予 client
    
            (3) TCP 连接 的 套接字对(socket pair)`
    
                1) 定义 `TCP 连接 两端 的 2个套接字 的 4 元组:`
    
                    `本地 IP 地址 / 本地 TCP 端口号 / 外地 IP 地址 / 外地 TCP 端口号`
    
                    每个 `套接字` 即 `IP 地址 和 端口号`
    
                2) `唯一标识` 一个网络上 `每个TCP 连接`
    

    相关文章

      网友评论

        本文标题:<< UNIX 网络编程 卷1>> 第1&2章: TCP/IP

        本文链接:https://www.haomeiwen.com/subject/kqlbeltx.html