TCP报文格式
每行简介
1.源端口和目的端口各占2个字节,即16位。
2.32位序号,占4个字节,TCP连接中传送的字节流中每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始。
3.32位确认序号。是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。
4.数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远。
5.保留,占6位,保留今后使用,但目前应都位0。
6.标志位字段(U、A、P、R、S、F):占6比特。各比特的含义如下:
◆URG:紧急指针(urgent pointer)有效。
◆ACK: 确认ACK,当ACK=1时,确认序号才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1。
◆PSH:为1时,接收方应该尽快将这个报文段交给应用层。
◆RST:为1时,重建连接。
◆SYN:在建立连接时为同步序号。当SYN=1,ACK=0表明是请求连接报文,若同意连接,则相应报文为SYN=1,ACK=1。
◆FIN::标记数据是否发送完毕。如果FIN=1,就相当于告诉对方:“我的数据已经发送完毕,你可以释放连接了”。
7.窗口,占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受。
8.16位校验和,检验首部和数据这两部分。
9.紧急指针字段:占16比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
10.选项,长度可变,定义一些其他的可选的参数。可能包括”窗口扩大因子”、”时间戳”等选项。
TCP连接的建立(三次握手)
连接如上图。TCP是面向连接协议。即无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接,建立一条连接有以下过程。
1.请求端(客户端)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序列号(ISN),这个**SYN为报文段1,即说明要建立连接了。同时选择一个初始序列号 seq=x **。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
2.TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中标志位ACK=1,SYN=1,确认序号是ack=x+1,同时也要自己初始化一个序列号 seq=y,这个生成序列号seq必须比客户端的大,即y>x。此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。此时客户端可以确定自己接收与发送消息没有问题。
3.TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。此时服务端也确定自己发送的消息客户端可以接收。
4.这三个报文段完成连接的建立,这个过程成为三次握手。
TCP连接的释放(四次挥手)
1.客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2.服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
3.、服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
4.客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗*∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
5.服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据(即一方发送FIN只表示自己发完了所有要发的数据,但还允许对方继续把没发完的数据发过来),而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
TCP如何保证可靠性
• 数据包校验
• 超时重传机制
• 应答机制
• 对失序数据包重排序
• TCP还能提供流量控制
三次握手总结:TCP协议是传输层的一个面向连接的安全可靠的一个传输协议,三次握手的机制是为了保证能建立一个安全可靠的连接,那么第一次握手由客户端发起,客户端会向服务端发送一个报文,在报文里面:SYN标志位置为1,表示发起新的连接。服务端收到这个报文之后就知道客户端发送一个确认消息包,在这个消息包里面:ACK标志位置1,表示确认客户端发起的第一次连接请求。两次握手之后客户端确认可以向服务端收发信息,服务端只能知道客户端发消息能收到,但不知道客户端能不能收到我发的消息。因此进行第三次握手,第三次握手就是当客户端收到服务端发送的确认响应报文之后,还要继续给服务端进行回应,也是一个ACK标志位为置为1的确认消息。通过三次握手,客户端或者服务端都知道双方能发消息和能接收响应。
再附一张processon的三次握手和四次挥手图吧。
。