TCP数据包格式:
源端口、目的端口用于确认应用程序
序号:指出段中的数据部分在发送方数据流中的位置,会随着时间增加。主要是为了解决TCP数据包传输过程中乱序的问题。
确认序号:指出接收方希望收到对方下次发送数据的第一个字节的序号。与序号是对应的,服务端对客户端发来的数据包进行确认。
URG位:紧急标志,和紧急指针配合使用,当其为1时,表示此报文要尽快发送。
ACK位:确认标志,和确认序号字段配合使用,当ACK位置为1时,确认序号字段有效。
PSH位:推送标志,置1时,发送方将立即发送缓冲区中的数据。
RST位:复位标志,置1时,表示有严重错误,必须释放连接
SYN位:同步标志,置1时,表示请求连接
FIN位:终止标志,置1时,表明数据已经发送完,请求释放连接
窗口大小:用于向对方通告当前本机的接收缓冲区的大小。
TCP传输时有以下几个特点:
1、顺序问题,会保证顺序传输
2、丢包问题,丢包后会进行重传
3、连接维护,传输前会先进行连接
4、流量控制,会控制传输的流量大小
5、拥塞控制,控制发送的速度
TCP三次握手:
第一次握手:客户端发送syn包,表示请求连接,序号seq=x,到服务器,进入SYN_SENT状态,等待服务器确认。
第二次握手:服务器收到syn包,必须进行确认,也发送SYN、ACK包,确认序号ack=x+1,序号seq=y,即SYN+ACK包,此时服务器进入SYN_RCVD状态。
第三次握手:客户端收到服务器的SYN_ACK包,向服务器发送确认包ACK(确认序号ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
TCP连接为什么是三次握手而不是两次或者四次?
第一次握手是客户端向服务端发送请求,告知服务端我想要连接,快做好准备。
第二次握手是服务端响应客户端的请求,告知客户端我准备好了,你来连接吧。
第三次握手是客户端响应服务端的响应,告知服务端,你好了那我来了。
假如只有两次握手,第三次握手没了,客户端收到服务端的响应之后,没有往服务端发包,服务端就一直保持着连接,也就纳闷了,怎么客户端一直不发数据,那我这个连接状态还要不要保持。如果只有两次握手,服务端就无法确认给客户端发送数据包后,客户端还活着。
至于为什么不是四次,客户端发送给服务端响应的响应之后,服务端再回复个响应的响应的响应,这样下去,40次,400次都行,但根本没必要,只要三次,基本就保证了客户端和服务端的连接。
三次握手完成后,如果客户端一直不发送数据,服务端可以主动关闭,此外,一般设计时,可以开启keepalive机制,即使没有真实的数据包,也要有探活包。这里的keepalive机制与socket长链接那种貌似不是同一个意思,这里的keepalive是在操作系统层面进行设置,当一定时间内客户端或者服务端没有检测到数据包,就会发送探活包。
TCP四次挥手:
1、A对B说,我不玩了。A发送FIN包给B,序号seq=p,此时A进入FIN_WAIT_1状态。
2、B收到A的消息之后,对A说,好,我知道了。B发送一个ACK包给A,确认序号ack=p+1,此时B进入CLOSED_WAIT状态。A收到B的ack包之后,进入FIN_WAIT_2状态。
3、这个时候,B还是可以继续发送数据的,当B处理完之后,对A说:我也不玩了。B向A发送FIN、ACK包。
4、A收到B的确认退出消息后,对B说:好的,我知道了。A向B发送一个数据包。
A向B发送完数据包之后,会有一个TIME_WAIT时间,这个时间是防止A异常退出,端口被其他进程给占用了,导致B的数据包发送到其他进程去。在TIME_WAIT时间之后,B发给A的数据包早就死翘翘了。
总结:
1、TCP连接建立的时候经过三次握手,断开的时候四次挥手。
2、TCP传输主要涉及到五点:顺序问题、丢包问题、连接维护、流量控制、拥塞控制。
参考:https://www.cnblogs.com/feitian629/archive/2012/11/16/2774065.html
参考:趣谈网络协议