TCP是面向连接的,可靠的进程到进程通信的协议。
TCP提供全双工服务,即数据可在同一时间双向传输,每一个TCP都有发送缓存,用来临时存储数据。
TCP将若干个字节构成一个分组,成为报文段(segment)
TCP报文段封装在IP数据报中:
TCP报文段的首部格式如图:
首部长度为20--60字节,
源端口号:他是16位字段,为发送方进程对应的端口号。
目标端口号:他是16位字段,对应的是接收端的进程,接收端收到数据段后,根据这个端口号来确定把数据送给那个应用程序的进程。
序号:当TCP从进程接收数据字节时,就把他们存储在发送缓存中,并对每一个字节进行编号,编号的特点如下:
编号不一定从0开始,一般会产生一个随机数作为第一个字节的编号,成为初始序号(ISN)
TCP每个方向的编号都是互相独立的。
当字节都被编上号后,TCP就给每个报文段指派一个序号,序号就是该报文段中的第一个字节的编号
当数据到达目的后,接收端会按照这个序号吧把数据重新排列,保证数据的正确性
确认号:对发送端的确认信息,用它来告诉发送端这个序号之前的数据段都已经收到,如确认号是X,就是表示前X-1个数据段都已经收到
首部长度:用它可以确定首部数据结构的字节长度。一般情况下TCP的首部是20字节,但首部长度最大可以扩展为60字节
保留:这部分保留位供今后扩展功能使用,现在还没有使用到
控制位:这六位有很重要的作用,TCP的连接、传输和断开都受到这六个控制位的指挥。各位含义如下:
URG:紧急指针有效位
ACK:只有当ACK=1时,确认序列号字段才有效,当ACK=0时,确认号字段无效。
PSH:标志位为1时,要求接收方尽快将数据段送达应用层
RST:当RST值为1时,通知重新建立TCP连接
SYN:同步序号位,TCP需要建立连接时将这个值设为1
FIN:发送端完成发送任务位,当TCP完成数据传输需要断开连接时,提出断开连接的一方将这个值设为1
窗口大小:说明本地可接收数据段的数目,这个值的大小是可变的,当网络通畅时将这个窗口值变大以加快传输速度,当网络不稳定时减小这个值可保证网络数据的可靠传输,TCP中的流量控制机制就是依靠变化窗口的大小实现的
校验和:用来做差错控制,与IP的校验和不同,TCP校验和的计算包括TCP首部、数据和其他填充字节,在发送TCP数据段时,由发送端计算校验和,当到达目的地时又进行了一次校验和计算,若这两次的校验和一致,则说明数据基本是正确的,否则将认为该数据已被破坏,接收端将丢弃该数据
紧急指针:和URG配合使用,当URG=1时有效
选项:在TCP首部可以有多达40字节的可选信息
TCP连接:
TCP是面向连接的协议,它在源点和终点之间建立一条虚连接。TCP报文段封装成IP数据报后,每一个IP数据报可以走不同的路径到达终点,因此收到的IP数据报可能不按顺序到达,甚至可能丢失或损坏。如果一个报文段没有按顺序到达,那么TCP保留它,然后等待它之前的报文段到达;如果一个报文段丢失或损坏,那么TCP就要重传。总之,TCP保证报文段是有序的。
在数据通信之前,发送端与接收端要先建立连接;等待数据发送结束后,双方再断开连接。TCP连接的每一方都是由一个IP地址和一个端口号组成的。
TCP建立连接的过程称之为三次握手:
三次握手可以理解为两个人在打电话
A:你好,我是A,能听见说话么
B:听到了,我是B,你能听见我说话吗
A:可以的
第一次握手:客户端使用一个随机的端口号向服务器端的80/443端口发送建立连接的请求,此过程的典型标志就是TCP的SYN控制位为1,其他五个控制位全为0。
第二次握手:实际上是分两部分来完成的。当服务端接受到了客户端的请求,向客户端回复一个确认消息,此过程的典型标志就是TCP的ACK控制位为1,其他五个控制位全为0,而且确认序列号是客户端的初始序列号+1。
服务端也向客户端发送建立连接的请求,此过程的典型标志和第一次握手一样。
为了提高效率,一般将这两部分合并在一个数据包里实现。
第三次握手:客户端收到了服务端的回复(包含请求和确认),也要向服务端回复一个确认信息,此过程的典型标志就是TCP的ACK控制位为1,其他五个控制位全为0,而且确认序列号是服务端的初始序列号+1。
上图中Seq表示请求序列号,ACK表示确认序列号,SYN和ACK为控制位,可以看出SYN位只有在请求建立连接时才被设置为1。
TCP使用面向连接的通信方式,它提高了数据传输的可靠性,使发送端和接收端在数据正式传输之前就有了交互,为数据正式传输打下了可靠的基础。
TCP断开连接:
参加交换数据的双方中的任何一方(客户端或服务端)都可以关闭连接。TCP断开连接分四步,也称为四次握手,具体过程如下:
服务器向客户端发送FIN和ACK位置1的TCP报文段。
客户端向服务器返回ACK位置1的TCP报文段(此时已经单向断开了连接)。
客户端向服务端发送FIN和ACK位置1的TCP报文段。
服务端向客户端返回ACK位置1的TCP报文段。
在TCP断开连接的过程中,有一个半关闭的概念,TCP的一方(通常是客户端)可以终止发送数据,但仍然可以接受数据,称为半关闭。主要是用在客户端不需要发送数据了,会发送一个FIN报文段,半关闭这个连接,服务器发送ACK报文段接受半关闭,服务端会继续传输数据,而客户端只发送ACK确认,不再发送任何数据。当服务端把所有的数据发送完毕时,就发送FIN报文段,客户端再发送ACK报文段,这样就断开了TCP连接。
为什么TCP协议终止连接要四次?
1、当客户端确认发送完数据且知道服务端已经接受完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给服务端。
2、服务端收到客户端发送的FIN,表示收到了,就会发送ACK回复。
3、但这时服务端可能还在发送数据,没有想要关闭数据口的意思,所以FIN与ACK不是同时发送的,而是等到服务端数据发送完了,才会发送FIN给客户端。
4、客户端收到服务端发来的FIN,知道服务端的数据也发送完了,回复ACK, 客户端等待2MSL以后,没有收到B传来的任何消息,知道服务端已经收到自己的ACK了,客户端就关闭连接,服务端也关闭连接了。
原文地址:https://blog.51cto.com/14227204/2391334