一、 TCP协议
TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。
TCP的特点有:
1. TCP是面向连接的运输层协议
2. 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
3. TCP提供可靠交付的服务
4. TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。
5. 面向字节流。面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流
TCP报文首部,如下图所示:
1. 源端口号:数据发起者的端口号,16bit
2. 目的端口号:数据接收者的端口号,16bit
3. 序号:32bit的序列号,由发送方使用
4. 确认序号:32bit的确认号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。
5. 首部长度:首部中32bit字的数目,可表示15*32bit=60字节的首部。一般首部长度为20字节。
6. 保留:6bit, 均为0
7. 紧急URG:当URG=1时,表示报文段中有紧急数据,应尽快传送。
8. 确认比特ACK:ACK = 1时代表这是一个确认的TCP包,取值0则不是确认包。
9. 推送比特PSH:当发送端PSH=1时,接收端尽快的交付给应用进程。
10. 复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。
11. 同步比特SYN:在建立连接是用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。
12. 终止比特FIN:FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接。
13. 窗口:用来控制对方发送的数据量,通知发放已确定的发送窗口上限。
14. 检验和:该字段检验的范围包括首部和数据这两部分。由发端计算和存储,并由收端进行验证。
15. 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。
16. 选项:长度可变,最长可达40字节
注意:URG紧急指针和PSH推送的区别
1)URG紧急位
URG标志URG紧急指针有效。当URG=1时,表示分段中有紧急数据应当加速传送。其中的紧急数据需要直接交付给接收端的进程,而不进入缓存。
二、 TCP连接
其实,网络上的传输是没有连接的,包括TCP也是一样的。而TCP所谓的“连接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一样。所以,TCP的状态变换是非常重要的。
下面是:“TCP协议的状态机”(图片来源) 和 “TCP建链接”、“TCP断链接”、“传数据” 的对照图
接下来是一个具体的例子。
建立连接
首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。
附:
我们看到在client发送请求的时候,mss值为1460?这个值是怎么来的呢?
首先数据在传输的时候需要经过数据链路层(MAC)、网络层(IP)、传输层(TCP),我们知道一般在数据链路层采用的是以太网,而以太网的MTU(最大传输单元)为1500字节,IP数据报的报文长度最少为20字节,TCP的报文长度最少为20,所以最多能传送的数据的个数就是1460.
断开连接
【注意】中断连接端可以是Client端,也可以是Server端。
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!(这也是为什么需要四次挥手的原因)
整个过程Client端所经历的状态如下:
而Server端所经历的过程如下: