-
TCP包头中的序号是为了解决乱序的问题,给包编号可以确定先来后到。
-
TCP包头中的确认序号是为了解决不丢包的问题,发出去的包应该需要确认对方是否收到,如果没有收到就应该重新发送,直到送达。
-
从IP层面来讲,如果网络状况比较差,则IP层的数据是没有任何可靠性保证的,而作为IP层的上一层TCP也无能为力,TCP层唯一能做的就是不断重传,在它的层面上通过各种算法保证努力保证可靠性。
-
TCP包头中的状态位比如:发起一个连接SYN,回复ACK,重新连接RST,结束连接FIN等。TCP是面向连接的,因而双方要维护连接的状态,这些带状态位的包的发送,会引起双方的状态变更。
- TCP包头中的窗口大小是为了做流量控制,通信双方各声明一个窗口,标识自己当前能够处理的能力。TCP还会做拥塞控制,控制发送的速度。
-
TCP的连接建立,常称为三次握手,因为三次就可以做到双方的消息都有去有回。具体过程如下:
A.第一次握手是由客户端向服务端发起的,是用来去发起一个连接建立的请求,在报文中,SYN位会被标记为1,序列号为x;
B.第二次握手是由服务器向客户端发起的,是服务器来确认一个请求连接的,在报文中,ACK位和SYN位都会被标记为1,序列号为y,确认报文x(ack = x + 1);
C.第三次握手是客户端发给服务器的,是对服务器的上一个报文的一个确认报文,这个报文中的ACK被标记为1,序列号为x+1,确认报文y(ack = y + 1)。
概括为:客户端 -> SYN -> 服务端
服务端 -> SYN/ACK -> 客户端
客户端 -> ACK -> 服务端
-
三次握手除了双方建立连接外,主要还是为了沟通TCP包的序号的问题。每个连接都要有不同的序号,这个序号的起始序号是随着时间变化的。
- 双方建立连接后,为了维护这个连接,双方都要维护一个状态机,在连接建立的过程中,双方的状态变化时序图如图所示。具体为:
A.一开始,左边的客户端和右边的服务端都处于CLOSED状态,先是服务端主动监听某个端口,处于LISTEN状态;
B.然后客户端主动发起连接SYN,之后处于SYN-SENT状态;
C.服务端收到发起的连接,返回SYN,并且回复客户端的SYN,之后处于SYN-RCVD状态;
D.客户端收到服务端发送的SYN和ACK之后,发送ACK的ACK,之后处于ESTABLISHED状态;
E.服务端收到ACK的ACK之后,也处于ESTABLISHED状态。
- TCP的连接结束,常成为四次挥手。具体过程如下:
A.第一次挥手是客户端向服务器发起的,这个时候客户端已经完成了数据发送,会发起一个包去进行连接断开的请求,这个报文中的FIN位被标记为1,序列号为p;
B.第二次挥手是服务器发给客户端的,这个报文是用来确认上一个客户端断开连接请求的一个报文,ACK被标记为1,确认报文p(ack = p + 1);
C.第三次挥手同样是服务器发给客户端的,此时服务器的数据如果也发送完毕的话,服务器会向客户端发起一个断开连接的申请,在这个报文中,ACK和FIN位都会被标记为1,序列号为q,确认报文p(ack = p + 1);
D.第四次挥手是客户端发给服务器的,是用来确认服务器的上一个断开连接的,ACK位被标记为1,确认报文q(ack = q + 1)。
概括为:客户端 -> FIN -> 服务端
服务端 -> ACK -> 客户端
服务端 -> FIN -> 客户端
客户端 -> ACK -> 服务端
-
MSL是报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为TCP报文是基于IP协议的,而IP头中有一个TTL域,是IP数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送报文通知源主机。协议规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
- 将连接建立和连接断开的两个时序状态图综合起来,就得到著名的TCP状态机。
-
TCP协议为了保证顺序性,每一个包都有一个ID序号。在建立连接时,会商定起始的ID序号,然后按照ID一个个发送;为了保证不丢包,对于发送的包都要进行应答,但是这个应答不是一个个来的,而是会应答某个之前的ID,表示都收到了,这种模式称为累计确认或者累计应答。
- 为了记录所有发送的包和接收的包,TCP需要发送端和接收端分别都有缓存来保存这些记录。
-
发送端缓存里的包是按照包的ID一个个排列,根据处理的情况分成四个部分:
第一部分:发送了并且已经确认的。
第二部分:发送了并且尚未确认的。
第三部分:没有发送,但是已经等待发送的。
第四部分:没有发送,并且暂时还不会发送的。
-
发送端缓存区分第三和第四部分是为了做流量控制,在TCP里,接收端会给发送端报一个窗口的大小,这个窗口的大小应该等于第二部分加上第三部分,超过这个窗口的,接收端处理不过来,就不能发送。
- 对于接收端,它的缓存里记录三部分内容:
第一部分:接受并且确认过的。
第二部分:还没接收,但是马上就能接收的。
第三部分:还没接收,也没法接收的。
- 顺序问题、丢包问题、流量控制都是通过滑动窗口来解决。拥塞控制通过拥塞窗口来解决。