1.socket()
a.创建一个int类型的fd
b.内部有一个TCB控制块。TCB 是一个内核数据结构,包含多个字段来记录 TCP 连接的状态和相关信息。
在一个简单的 TCP 连接中,TCB 记录如下信息:
本地端口: 12345
远程端口: 80
本地地址: 192.168.1.10
远程地址: 93.184.216.34
发送序列号: 初始值为 1001
接收序列号: 初始值为 2001
状态: ESTABLISHED
操作系统通过五元来查找对应的TCB
2.bind()
把一个fd和对应的ip和端口绑定,没指明就是随机绑定。
3.listen()
a. 把TCB里status(状态)设置为listen
b.只有设置为listen状态才能正式接受客户端请求
c.为TCB分配一个全连接队列和半连接队列
4.三次握手(建立连接)
如上图所示:
三次握手的过程
TCP 三次握手包括以下三个步骤:
第一步:客户端发送 SYN
操作:客户端向服务器发送一个带有 SYN(synchronize,同步)标志的报文。
内容:包括客户端的初始序列号seq = J
状态变化:客户端从CLOSED 进入CONNECT状态。
作用:表示客户端希望建立连接,并同步序列号。
第二步:服务器发送 SYN-ACK
操作:服务器收到 SYN 后,回复一个带有 SYN 和 ACK(acknowledge,确认)标志的报文。
内容:确认客户端的序列号 ACK = J + 1
。同时发送服务器自己的初始序列号 seq = y
。
状态变化:服务器从 LISTEN
进入 accept状态。
作用:确认收到客户端的请求,同时发送自己的序列号以同步。
第三步:客户端发送 ACK
操作:客户端收到 SYN-ACK 后,回复一个带有 ACK 标志的报文。
内容:确认服务器的序列号 ACK = J + 1
。
状态变化:客户端进入 ESTABLISHED
状态。服务器收到 ACK 后也进入 ESTABLISHED
状态。
作用:完成连接的建立,双方可以开始数据传输。
三次握手的作用
确保连接的可靠性:双方都确认了自己的发送能力和对方的接收能力。初始序列号的同步为后续数据传输提供基础。
防止重复连接:通过序列号,可以避免因网络延迟导致的重复连接请求对现有连接的干扰。
初始化资源:三次握手期间,双方分配必要的缓存和控制块(如 TCB),为后续通信做准备。
三个问题:
a.tcp的生命周期:从listen接收到数据包,协议栈会为它分配一个tcp连接,这时候就已经开始了
b.三次握手数据包,如何从半连接队列查找匹配的节点:用5元来查找
c.syn翻洪:listen(fd,backlog)中,backlog最早是syn队列(半连接队列)长度,就是在listen这一步的数据包长度,设置它可以限制数据包无限增长;后来改成syn+accept队列总长度,也被描述为未分配fd的tcb数量;第三种就是accept队列的长度,这种方法可以增大建立连接的数量,增大服务器的吞吐量。
5.数据传输
几个概念:
a.滑动窗口:可允许的未确认的最大数据发送量,假如滑动窗口大小是4500,那么在客户端没有发回ack之前最多只可以发送4500大小的数据。
b.慢启动、拥塞控制:在数据传输的最开始阶段,滑动窗口的增长是指数级的,达到某一个阈值后呈线性增长。逐步探测网络的承载能力,避免一开始发送过多数据导致拥塞。
6.四次挥手(断开连接)
四次挥手的具体过程
第一步:客户端发送 FIN
客户端向服务器发送 FIN 报文,表示客户端已经完成数据发送,请求关闭客户端到服务器的方向连接。客户端进入 FIN_WAIT_1
状态。FIN 报文包含序列号(seq=x
)。
第二步:服务器回复 ACK
服务器收到 FIN 报文后,发送一个 ACK 报文,表示已经确认客户端请求关闭连接。服务器进入 CLOSE_WAIT
状态。客户端进入 FIN_WAIT_2
状态,等待服务器的 FIN 报文。ACK 报文包含序列号 ack=x+1
,表示确认了客户端的 FIN。
第三步:服务器发送 FIN
服务器在确认客户端的 FIN 后,发送自己的 FIN 报文,表示服务器也完成数据发送,请求关闭服务器到客户端的方向连接。服务器进入 LAST_ACK
状态,等待客户端的最终确认。FIN 报文包含序列号(seq=y
)。
第四步:客户端回复 ACK
客户端收到服务器的 FIN 报文后,发送一个 ACK 报文,表示确认了服务器的 FIN。客户端进入 TIME_WAIT
状态,等待一段时间(通常为 2 * 最大报文生存时间,2 * MSL)后关闭连接。服务器收到 ACK 后立即进入 CLOSED
状态,释放连接资源。客户端在 TIME_WAIT
状态超时后也进入 CLOSED
状态。ACK 报文包含序列号 ack=y+1
,表示确认了服务器的 FIN。
四次挥手的设计是为了保证双方都能完全关闭连接,并且确认所有的数据都已成功传输:
a.半关闭机制:
TCP 是全双工通信,关闭一个方向的连接(如客户端到服务器)不意味着另一个方向也立即关闭因此需要双方各自独立地关闭自己的数据发送方向。
b.避免数据丢失:
在发送 FIN 后,TCP 需要确保接收方已经收到 FIN 报文,同时也需要确认所有未发送的数据都已被接收。