认识TCP
TCP是工作在网络层,向应用层提供一种可靠的,面向字节流的协议。
1.TCP的首部
TCP首部通常占用20字节。
TCP首部中的两个记录端口的字段再加上IP首部中的源IP和目的IP来确认一个唯一的TCP连接。
序号用来标识TCP的发送端发送的字节流,每发送一个字节,序号就加一。
为什么图中SEQ是从1开始呢?因为在TCP连接的是否发送了一个只包含SYN的包,将SEQ初始为1,从图中可以看出序号对单向传输的每一个字节进行计数。
确认序号是用来确认前面收到的字节。
从图中可以看出第355号包确认的是第354的seq加上len再加一。如果发送方的包在传输过程中出错,导致接收方的检验和对不上,这样将不会确认这个包,例如A能接受B的1024~2047,但是其中数据出现错误的话,A只会确认1025。这样发送方收到重复的ACK,如果这样发生三次这样就能判断这个包丢包或者发生错误,发送方就会重传这个包。
下面介绍TCP首部中六个标志位:
URG:紧急指针有效、
ACK:确认序号有效
PSH:接收方应该尽快将这个报文交给应用层、
RST:复位标志,表示需要重新连接
SYN:请求连接
FIN: 结束连接(双方都可发起)
检验和检验的范围包括了整个TCP报文(TCP首部和TCP数据)和一个12字节伪首部(包含源IP,目的IP等),由一定由发送方计算和储存,由接收方进行检验对比。
最常见的可选字段是MSS字段(最大报文大小),指明本端能接受的最大报文的大小,通常在通信的第一个报文中表明。
**
2.TCP连接的建立和断开
**
1.TCP的连接
从上图中可以看出TCP连接通常是由三次通信建立的,统称“三次握手”。
第一步:客户端A向服务端B发送SYN报文请求连接。客户端从CLOSED状态变为SYN-SENT状态。
第二步:服务端B确认A发来的SYN,并且也发出SYN请求连接。从LISTEN状态变为SYN-RCVD状态。
第三步:客户端A接收到来自服务端B的SYN和ACK报文从SYN-SENT状态变为ESTABLISHED状态并对服务端的SYN进行确认,服务端B接收到来自A的ACK报文,从SYN-RCVD变为ESTABLISHED状态,然后就能进行数据传输。
为什么是三步呢,而不是两步或者四步?
首先我们假设是两次握手,那就是到服务端B发送SYN+ACK这一步为止。我们现在来假设一下,如果服务端B发送的这个报文段在中途丢包,客户端A没有收到这个包,A的连接状态就不会改变,B也永远不会知道这个报文段是否到达A,这是否是一个可靠的连接。这样就无法保证连接的可靠性。
那为什么不是四次握手呢?因为前面三次已经保证了这个连接是可靠的连接了,所以第四次完全是多余的。
/*********************************************************************************/
讲完正常的连接情况,我们现在来讲讲一些特殊情况和连接中的异常情况:
两次连接的情况
当主机A和主机B同时向对方发出连接的请求,所以在这种情况下就不存在客户端和服务端之分了
两次挥手的情况
上面既然有两次连接的情况,同理当然也会有两次挥手的情况,那就是主机A与主机B同时关闭,向对方发出带FIN的报文段并且同时回复对方带有FIN+ACK的报文。
在这种情况下,两台主机都不经过FIN_WAIT_2状态。
虽然上面这两种情况非常少见,但是还是会发生。
#