OSI模型
- 网络层由IPv4和IPv6这两个协议处理。
- OSI模型的顶上三层被合并成一层,称为应用层。这就是Web客户(浏览器)、Telnet客户、
Web服务器、FTP服务器和其他我们在使用的网络应用所在的层。 - 本书讲述的套接字编程接口是从顶上三层(网际协议的应用层)进入传输层的接口。
传输层
TCP的建立和终止
三次握手:
- 服务器进入Listen状态准备接受外来连接。这通常通过socket,bind和listen3个函数实现。
- 客户端通过调用connect发起主动打开,导致客户TCP发送一个SYN分节(请求报文),该报文段首部中的SYN=1,同时选择一个初始序列号seq=i,发送完毕后,客户端就进入 SYN_SENT 状态。
- 服务端确认连接,同时自己也发送一个SYN确认报文 (SYN=1, ACK=1, seq=y, ACKnum=i+1), 发送完毕后,服务器端就进入 SYN_RCV 状态。
- 客户端收到服务端的确认之后,再次向服务端确认,(确认报文段的ACK=1,ACKnum=i+1),发送完毕后,客户端进入 ESTABLISHED 状态。当服务器端接收到这个包时,也进入 ESTABLISHED 状态。
四次挥手:
- 某个应用程序首先其先调用close,导致TCP进程发送FIN分节(释放连接报文),第一次挥手 (FIN=1,seq=u),发送完毕后,客户端进入 FIN_WAIT_1 状态。
- 服务端接收到后,发送确认报文,第二次挥手 (ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态。
- 服务端发送释放连接报文,第三次挥手 (FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个 ACK。
- 客户端发送确认报文,第四次挥手 (ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT 状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
![[uTools_1693902605157.png]]
TIME_WAIT状态
目的:可靠的实现TCP全双工连接的终止。
允许老的重复字节在网络中消逝。
![[uTools_1693902740822.png]]
端口号
多个进程可能同时使用TCP,UDP和SCTP这三张传输层的协议中的任意一种。他们也都是用16位整数的端口号来区分这些进程。
TCP端口号和并发服务器
并发服务器中主服务器循环通过派生一个子进程来处理新的连接。
TCP无法仅仅通过查看目的端口号来分离外来的分节到不同的端口。它必须查看套接字对的所有4个元素才能确定由那个端口接收某个到达的节点。
缓冲区大小和限制
- IPV4和IPV6都定义了最小重组缓冲区大小,前者是576字节,后者1500字节。
- MSS:向对端TCP通告对端在每个字节中能发送的最大TCP数据量。
MSS的目的在于告诉对端其重组缓冲区大小的实际值,从而试图避免分片。MSS经常被设置为MTU减去IP和TCP首部的固定长度。以太网的MTU最大传输单元是1500。
TCP输出
上图展示了一个应用进程写数据到一个TCP套接字中发生的步骤
每个TCP套接字有一个发送缓冲区。当某个应用进程调用write时,内核从该应用进程的缓冲区中赋值所有数据到套接字发送缓冲区。如果该套接字发送缓冲区容不下所有数据,该应用进程进入睡眠。
UDP输出
任何UDP套接字都有发送缓冲区大小,不过它仅仅是可以写到该套接字的UDP数据包的大小上限,UDP是不可靠的,不必保存应用程序的数据副本,所有是无需一个真正的发送缓冲区。