【TCP协议】----传输控制协议TCP(1)
一、TCP协议概述
TCP协议具有以下特点:
1)TCP协议是面向连接的,工作在运输层。也就是说,TCP协议在传输数据之前需要先建立连接,传输结束后要释放连接。
2)每一条TCP连接是点对点的,只能有两个端点。
而端点是什么呢?
TCP连接的端点叫做套接字或插口。
套接字socket = (IP地址:端口号)
每一条TCP连接唯一地被通信两段的两个端点(即两个套接字)所确定。即:
TCP连接 ::={socket1,socket2}={(IP1: port1), (IP2: port2)}
3)TCP连接是可靠的。通过TCP连接可以无差错的传输数据,使数据不丢失、不重复且按序到达。
4)TCP提供全双工的通信。
5)面向字节流。所谓的面向字节流就是说:TCP把应用进程传下来的数据仅仅看成一连串无结构的字节流,并不知道字节流的含义。
二、TCP协议报文段和首部格式
TCP报文段=首部+数据
(图片来源于网络,侵删)
由图可知,TCP报文段包含在IP数据报中,IP工作在网络层(第三层),当数据从应用层向下传输时需要加上每一层的首部,封装后进行传输,需要注意的是在数据链路层(第二层)不仅需要加首部,还要加上尾部,然后到达物理层通过物理媒体发送出去(物理层不需要加首部信息),然后再一步层层将控制信息剥去,上交给更高一层,直到到达接收端的应用层为止。这是数据的基本传输流程。
接下来重点介绍一下TCP首部固定部分各字段的意义:
源端口和目的端口
各占2个字节,这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时一个IP地址和一个端口号也称为socket(插口或套接字)。
序号(seq)
占4个字节,是本报文段所发送的数据项目组第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。例如,一报文段的序号为300,而且数据共100字节,下一个字节的序号是301,则下一个报文段的序号就是400;序号是32bit的无符号数,序号到达2^32-1后从0开始。
确认序号(ack)
占4字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号;确认序号应该是上次已成功收到数据字节序号+1,如上,报文段的序号为300,则确认序号为399+1=400(399为第100个字节的序号)。只有ACK标志为1时,确认序号才有效。
应当记住:确认序号为N,则说明到(N-1)为止的数据都已经正确收到了。
数据偏移
占4位,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,也就是4个字节,因此TCP首部的最大长度是60个字节。即偏移最大为15个长度单位=1532位=154字节。
保留
6位,供以后应用,现在置为0。
6个标志位比特
① 紧急URG:当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,使接管方可以知道紧急数据共有多长。
② 确认ACK:只有当ACK=1时,确认序号字段才有效;
③ 推送PSH:当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。
④ 复位RST:当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接;
⑤ 同步SYN:在建立连接时用来同步序号,SYN=1,ACK=0时表示请求建立一个连接,携带SYN标志的TCP报文段为同步报文段;
⑥终止 FIN:发端完成发送任务。
窗口
TCP通过滑动窗口的概念来进行流量控制。
设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制, 协调好通信双方的工作节奏。
所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓 冲区。窗口大小为字节数起始于确认序号字段指明的值(这个值是接收端正期望接收的字节)。
窗口大小是一个16bit字段,因而窗口大小最大为65535字节。
应当记住:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常动态变化。
检验和
占2字节,检验和覆盖了整个TCP报文段:TCP首部和数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
紧急指针
只有当URG=1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号,指出了本报文段中的紧急数据的字节数(紧急数据之后就是普通数据)。
参考资料:
《计算机网络 第七版》谢希仁编著
https://www.cnblogs.com/qdhxhz/p/10267932.html
最后的话:我是喋喋,一个正在努力学习测试的人er~,如果文章中有什么不正确的地方,还希望大佬在评论区指出,非常感谢!