- 源端口(2字节)
- 目的端口(2字节)
- 序号(4字节)报文发送的长度的首个序列号
- 确认号(4字节)报文回复下一次需要发送的序号等同于此次的确认号
- 数据偏移(4位)TCP报文数据到TCP报文段的起始处距离
- 保留(6位)
- 紧急URG,URG=1表示紧急字段有效,告诉系统此报文段中有紧急数据
- 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定在建立连接后所有报文的传输 都必须把ACK置1
- 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能
收到对方的响应,这时候就将PSH=1 - 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接
- 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响
应报文中应该使SYN=1,ACK=1 - 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放
- 窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受
- 检验和,占2字节,校验首部和数据这两部分
- 紧急指针,占2字节,指出本报文段中的紧急数据的字节数
- 选项,长度可变,定义一些其他的可选的参数。
- 握手过程如下图
描述:开始时客户端和服务端都是处于连接关闭状态Close,客户端首先发起请求syn=1,seq=x,
状态又Close转转变到SYN-SENT(syn=1是请求通信,seq=x是发送的报文尾序列号),服务端
状态是开启了服务Close转变到Listen状态,接着收到可客户端发送的数据(syn=1,ack=x+1,seq=y,ACK=1)
(报文的含义就是请求同步,然后希望客户端下次的报文是x+1序列号,我的报文就是y序列号)ACK是
确认信号。然后服务端的状态由Listen转变称为syn-rcvd,这个时候已经完成两次握手了,客户端收到
服务端的信息,发送(ACK=1,seq=x+1,ack=y+1)(确认消息,发送x+1开始的,希望下次收到的是y+1开始)
然后客户端状态由syn-sent转换到established状态,服务端收到了报文后由syn-rcvd转换到established
连接完成。
-
挥手过程下图
描述:首先客户端和服务端都处于建立连接状态(established),接着客户端发送(FIN=1,seq=u)然后状态转变成为FIN-WAIT-1,服务端收到了客户端的请求,发送确认(ACK=1,seq=v,ack=u+1)然后状态转变成为CLOSE-WAIT状态,客户端收到后状态由FIN-WAIT-1转变到FIN-WAIT-2,然后服务端再次发送一个报文进行数据传输(FIN=1,ACK=1,seq=w,ack=u+1)状态转变成为LAST-ACK,客户端状态又FIN-WAIT-2转变成为TIME-WAIT并且发送(ACK=1,seq=u+1,ack=w+1),服务端收到后状态转变成为CLOSED,客户端在TIME-WAIT上等待2MSL,然后状态转变成为CLOSED,连接断开保活定时器:
TCP中客户端断开连接后开启保活定时器2小时后,就是每隔75秒发送一次探测报文,然后发送十次(还是九次)
后还没收到客户端回复就会认为,这个客户端已经在某些因素下断开连接11种状态
- LISTEN:等待从任何远端TCP 和端口的连接请求
- SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求
- SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认
- ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态
- FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认
- FIN_WAIT_2:等待远端TCP 的连接终止请求
- CLOSE_WAIT:等待本地用户的连接终止请求
- CLOSING:等待远端TCP 的连接终止请求确认
- LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
- TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认
- TIME_WAIT 两个存在的理由:
1.可靠的实现tcp全双工连接的终止;
2.允许老的重复分节在网络中消逝
12.CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)
-
TCP的拥塞控制
慢开始,到ssthresh就进行拥塞避免(加法增大)
快重传:发送端一连收到三个重复确认报文就执行快重传,快重传配套快恢复。
常见问题- TCP为什么要三次握手?
防止已经失效的连接请求报文突然又传到服务端,服务回复报文后,如果是两次握手,那么连接又会建立,浪费资源,如果是三次握手,客户端收到服务端的请求连接报文后,直接不回复,所以三次握手能够规避掉这样的超时连接报文带来的错误情况(保证连接双工) - TCP的可靠性是通过什么实现的?
可靠性是通过重传机制来保证的,TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。TCP 的可靠传输机制用字节的序号进行控制。TCP 所有的确认都是基于序号而不是基于报文段。发送过的数据未收到确认之前必须保留,以便超时重传时使用。发送窗口没收到确认不动,和收到新的确认后前移。 - 发送缓存用来暂时存放: 发送应用程序传送给发送方 TCP 准备发送的数据;TCP 已发送出但尚未收到确认的数据。
- 接收缓存用来暂时存放:按序到达的、但尚未被接收应用程序读取的数据; 不按序到达的数据。
- 客户端和服务端的窗口并不总是一样大(有时间滞后)
- TCP标准没有对不按序到达的数据应该如何处理。通常是先临时存放在接收窗口中,等到字节流中缺少的字节收到后,在按序交付给上层。
- TCP要求接收方必须有积累确认功能,减小开销
- 为什么关闭连接需要四次挥手?
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,我们也未必全部数据都发送给对方了,所以我们不可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,我们的ACK和FIN一般都会分开发送。 - 为什么需要需要TIME-WAIT?
- 理由一:发送端发送ACK后,并不保证ACK一定会发送到接收端(可能会丢失)。存在2MSL能对确认ACK有保驾护航的作用。如果马上关闭,不经历TIME-WAIT,可能会发生ACK丢失,然后接收端发送FIN,发送端接收不到的情况,所以还是有必要等待2MSL
- 理由二:假设不经历TIME-WAIT,直接CLOSED,那么网路上存在这旧连接的数据包,假设新的连接也是同样的端口和IP,那么会出现数据包混乱的问题,所以先等2MSL等待网路上的数据包完全消失后,才经行新的连接
- TCP为什么要三次握手?