目录
TCP建立连接前:
1)需要对方的存在
2)允许协商参数,例如最大窗口等
3)对运输资源进行分配
客户:主动发起TCP连接的应用进程
服务器:被动等待连接的应用进程
1、TCP连接
TCP连接的过程称为握手,建立连接需要经过3次握手
说明:SYN为建立TCP连接的同步位
A为发送方,B为接收方
ACK:确认报文位
ack:确认号
seq:发送方要发送数据的开始序号
A、B建立连接时,均创建传输控制块TCB
字段/项 | 描述 |
---|---|
SYN | 用于建立TCP连接的同步位。发送方通过设置SYN标志位,表示请求建立连接。 |
A | 发送方(主动发起连接的一方)。 |
B | 接收方(响应连接请求的一方)。 |
ACK | 确认报文位。用于表示接收方确认收到数据或连接请求。 |
ack | 确认号。用于表示接收到的数据的下一个期望序列号。 |
seq | 发送方要发送数据的起始序列号。用于标识数据的顺序。 |
TCB (传输控制块) | 每个TCP连接在发送方和接收方各自维护一个传输控制块(TCB)。TCB包含了连接的状态、序列号、确认号等信息。 |
连接过程:
一、A向B发送请求,信息为:SYN=1,seq=x(不可携带任何数据)
意为:我请求建立连接,如我要发送数据,我从字节序号x开始
二、B收到A的请求,B向A发送确认连接:SYN=1,ACK=1,ack=x+1,seq=y(不可携带任何数据)
意为:我同意建立连接,确认号为x+1,我如要发送数据则从字节序y开始
三、A收到B的确认,随即A向B发送确认:ACK=1,seq=y+1(可携带数据)
注意:
上述连接过程需要经过3次握手
同时双方都需要消耗一个序号
问题:为什么要3次握手?当B向A回发确认不就可以确认建立了吗?2次不就可以了吗?
好问题。
假设我们就2次握手建立成功,现在考虑一种情况:(我叫他前夫哥陷阱)
当A第一次发送请求时,该请求报文被滞留在网络中,没有丢失,只是没有到达B。我们叫他1号请求报文
滞留超过A的超时重传时间,于是A认为该报文丢失,于是重新发了2号请求报文。
2号报文正常到达B,B向A回发确认建立,于是,连接建立
正常发送数据。
当一段时候后,不用了,于是释放,结束,over。
整个过程没有问题。
好,好得很,非常好,很棒!
可是,我们的2号请求选手这个时候被放出来
此时2号到达了B
B以为是A新发来的连接,因为请求报文都是一样的
于是B向A发送确认
当A收到B的确认的时候,懵逼了
A:我没有发请求连接啊
同时,A也不会向B发送任何确认和任何数据
于是,对于A来说,A没有建立连接
可是对于B来说,已经和A建立了连接
于是,B一直在等待数据,如此白白消耗B的资源,这是不应该的
因此,应当握手三次,避免上述前夫哥现象。
2、TCP释放
需经过4次握手。
过程:(FIN为终止位,用于释放连接)
一、A用完了,于是停止发送数据,主动关闭TCP连接,并且向B发送释放报文:FIN=1,seq=u
(A处于终止等待1)
二、B收到,向A发送释放确认。可是此时B还有数据没有发完,于是B继续发送,A继续接收:ACK=1,ack=u+1,seq=v
(B处于关闭等待,A处于终止等待2,TCP处于半关闭)
三、A收到确认,等待B释放,因为B还没有发完。当B发送完数据,于是释放TCP连接,向A发送释放报文:FIN=1,seq=w,ack=u+1
(B处于最后确认)
四、A收到B的释放报文,向B发送释放确认:ACK=1,ack=w+1,seq=u+1
(A、B均处于时间等待状态)
注意:完成上述四次握手,TCP连接依然没有释放,而是进入时间等待状态。
经过时间等待计时器设置的2MSL后,释放。
**问题:**A为什么发完第四次还要等?B发过来后,扔个确认过去,然后直接关不就行了吗?
好问题。
现在假设A发完确认关闭就直接关,考虑一种情况:
如果A给B发送的确认关闭的报文丢失,那么B将得不到A的确认关闭报文
对于B没收到回复,于是认为报文丢失,重传
可是!你A发完直接就关闭了!
(你是吃饱饭了,可是你吃完饭就直接把桌子给掀了。)
B:你怎么这么私自!
B重发的一切报文都将石沉大海,永远得不到回应
于是,B无法按正常步骤进行TCP的释放
所以,A得等。
如果回复ACK丢失,他得兜底
同时,A等待一段时间,有好处
在这段时间内,A、B之间的所有报文要么丢失,要么都已经到达对方
也就是说,对于关闭连接之前的互相传输的所有报文都已经完成了使命
此后关闭,不会留任何的历史问题
3、保活计时器
为避免客户端突然故障
服务器设立保活计时器,一般为2小时
2小时内没有收到任何客户数据,则发送探测报文
每隔15s发一个探测,如果10次都没有得到响应
则服务端认为客户端故障,主动关闭TCP连接。