【计算机网络】传输层TCP协议1

简介: 【计算机网络】传输层TCP协议

认识TCP协议

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠的、基于字节流的传输层协议。TCP协议是互联网协议栈中最重要的协议之一,它提供了可靠的数据传输服务,保证了数据的完整性、可靠性和有序性。


TCP协议通过建立连接、传输数据和断开连接三个步骤来完成数据传输。在建立连接时,双方需要通过三次握手协议来确认彼此的身份和可用性。在传输数据时,TCP协议会把数据分割成TCP数据包,并对每个数据包进行编号和校验,确保数据的完整性和有序性。在断开连接时,双方需要通过四次挥手协议来协商关闭连接。


TCP协议还提供了流量控制和拥塞控制功能,以便在网络拥塞或带宽限制的情况下保证数据传输的顺畅。此外,TCP协议还支持多路复用,可以在同一个连接上传输多个应用程序的数据。


总之,TCP协议是一种可靠、安全、高效的传输层协议,广泛应用于互联网中。

TCP协议的格式

字段的含义

  • 源端口和目的端口:源端口是发送端口,目的端口是接收端口。它们分别占用16个比特,总共32个比特。
  • 序号与确认序号:序列号表示TCP报文段中第一个字节的序列号,确认号表示期望接收到的下一个字节的序列号。它们各占用32个比特,总共64个比特。
  • 数据偏移:其中填充了TCP报头的长度,以4字节为单位,一般为20字节,最长为60字节(20字节的固定首部加上加上选项的大小)。
  • 保留字段:TCP报头中暂未被使用的6个比特位。
  • 控制位:包括URG、ACK、PSH、RST、SYN和FIN六个标志位,用于指示TCP报文段的不同控制信息。
  • 窗口大小:保证TCP通信的可靠性和效率的字段。
  • 校验和:包括TCP报头和TCP数据两部分,校验和用于检测TCP报文段中是否有错误,占用16个比特。
  • 紧急指针:用于指示紧急数据的位置,占用16个比特,需要配合标志位中的URG标识使用。
  • 选项和填充:选项用于扩展TCP报文段,占用可变长度,填充用于对齐TCP报文段的长度,占用可变长度。最大40字节。

序号与确认号

32位序号:

如果双方在进行数据通信时,只有收到了上一次发送数据的响应才能发下一个数据,那么此时双方的通信过程就是串行的,效率可想而知。

因此双方在进行网络通信时,允许一方向另一方连续发送多个报文数据,只要保证发送的每个报文都有对应的响应消息就行了,此时也就能保证这些报文被对方收到了。


但在连续发送多个报文时,由于各个报文在进行网络传输时选择的路径可能是不一样的,因此这些报文到达对端主机的先后顺序也就可能和发送报文的顺序是不同的。但报文有序也是可靠性的一种,因此TCP报头中的32位序号的作用之一实际就是用来保证报文的有序性的。


TCP将发送出去的每个字节数据都进行了编号,这个编号叫做序列号。


比如现在发送端要发送3000字节的数据,如果发送端每次发送1000字节,那么就需要用三个TCP报文来发送这3000字节的数据。此时这三个TCP报文当中的32位序号填的就是发送数据中首个字节的序列号,因此分别填的是1、1001和2001。

当接收方收到这三个报文之后,就会根据其中的序列号进行排序,排序完成后再放入TCP缓冲区中,这样就能保证发送出去的和接收到的数据顺序保持一致。

32位确认号:

TCP报头当中的32位确认序号是告诉对方,当前已经收到了哪些数据,并且数据下一次应该从哪里开始发送

以上文的例子为例,当主机B收到主机A发送过来的32位序号为1的报文时,由于该报文当中包含1000字节的数据,因此主机B已经收到序列号为1-1000的字节数据,于是主机B发给主机A的响应数据的报头当中的32位确认序号的值就会填成1001。


  • 一方面是告诉主机A,序列号在1001之前的字节数据我已经收到了。
  • 另一方面是告诉主机A,下次向我发送数据时应该从序列号为1001的字节数据开始进行发送。

如果报文在传输过程中丢失了,例如最终只要序号为1和2001的报文被主机B收到,那么当B对报文进行排序的时候,就会发现少了1001 ~ 2000 之间的数据,那么此时向主机A响应的报文中的32位确认序号的值就是1001,告诉主机A下次再次发送1001开始的数据。


【注意】

如果此时主机B在给主机A响应时,其32位确认序号不能填3001,因为1001-2000是在3001之前的,如果直接给主机A响应3001,就说明序列号在3001之前的字节数据全都收到了。因此主机B只能给主机A响应1001,当主机A收到该确认序号后就会判定序号为1001的报文丢包了,此时主机A就可以选择进行数据重传。


TCP报头中有了序号和确认号的机制,一定程度上保证了数据传输的完整性,同时也保证了TCP传输的可靠性。

六个标志位

TCP报文的种类多种多样,除了正常通信时发送的普通报文,还有建立连接时发送的请求建立连接的报文,以及断开连接时发送的断开连接的报文等等。收到不同种类的报文时需要对应执行动作,因此需要用标志位进行区分不同的报文类型。这六个标志位都只占用一个比特位,为0表示假,为1表示真。


URG:


双方在进行网络通信的时候,由于TCP是保证数据按序到达的,即便发送端将要发送的数据分成了若干个TCP报文进行发送,最终到达接收端时这些数据也都是有序的,因为TCP可以通过序号来对这些TCP报文进行顺序重排,最终就能保证数据到达对端接收缓冲区中时是有序的。


虽然TCP的有序到达是我们想要的目的,并且接收方的对端上层也是从接收缓冲区中按顺序读取的,但是有时候发送方也会发送紧急数据,那么就要让接收方的对端上层也要紧急读取该数据,因此就需要使用的URG标志位。

  • 当URG标志位设置位1时,需要使用TCP报头中的16位紧急指针找到紧急数据,因此一般情况下不会使用到报头中的紧急指针。
  • 16位紧急指针表示了紧急数据在报文中的偏移量。

ACK:

  • 报文中的ACK标志设置为1,表示该报文可以对接收到的报文进行确认。
  • 一般除了第一个请求连接的报文没有设置ACK外,其余报文基本上都设置了ACK,因为携带了ACK的报文需要对接收到的报文进行确认。

PSH:


当PSH标志位设置为1时,会提示接收端应用程序立刻从TCP缓冲区读取数据,并交付给上层应用。


一般我们会认为当使用read从缓冲区读取数据时,如果缓冲区中有数据,那么这些数据就会被返回,如果没有数据就会阻塞式的等待write向缓冲区中写入数据再进行读取。


其实这种说法并不准确,因为在缓冲区中都有应该水位线的概念,例如下图:

  • 当缓冲区存储的数据没有达到水位线的时候,read就会进行阻塞等待,只要超过水位线后才会进行读取。因为如果缓冲区中有一点数据就进行读取的话会导致频繁的调用read,势必会造成效率的低下。
  • 当报文当中的PSH被设置为1时,实际就是在告知对方操作系统,尽快将接收缓冲区当中的数据交付给上层,尽管接收缓冲区当中的数据还没到达所指定的水位线。

RST:

  • 报文当中的RST被设置为1,表示需要让对方重新建立连接。
  • 在通信双方在连接未建立好的情况下,一方向另一方发数据,此时另一方发送的响应报文当中的RST标志位就会被置1,表示要求对方重新建立连接。
  • 在双方建立好连接进行正常通信时,如果通信中途发现之前建立好的连接出现了异常也会要求重新建立连接。

SYN:

  • 报文当中的SYN被设置为1,表明该报文是一个连接建立的请求报文。
  • 只有在连接建立阶段,SYN才被设置,正常通信时SYN不会被设置。

FIN:

  • 报文当中的FIN被设置为1,表明该报文是一个连接断开的请求报文。
  • 只有在断开连接阶段,FIN才被设置,正常通信时FIN不会被设置。


窗口大小

当发送端要将数据发送给对端时,本质是把自己发送缓冲区当中的数据发送到对端的接收缓冲区当中。但缓冲区是有大小的,如果接收端处理数据的速度小于发送端发送数据的速度,那么总有一个时刻接收端的接收缓冲区会被填满,这时发送端再发送数据过来就会造成数据丢包,进而引起丢包重传等一系列的连锁反应。


因此TCP报头中就引入的16位窗口大小来加以控制。这个16位窗口中填充的就是自身缓冲区剩余空间的大小,发送给对方后就能让对方知道自己缓冲区的存储能力,从而控制传输的速率。


  • 窗口大小字段越大,说明接收端接收数据的能力越强,此时发送端可以提高发送数据的速度。
  • 窗口大小字段越小,说明接收端接收数据的能力越弱,此时发送端可以减小发送数据的速度。
  • 如果窗口大小的值为0,说明接收端接收缓冲区已经使用完了,此时发送端就不应该再发送数据了。

确认应答(ACK)机制

确认应答机制是保证TCP通信可靠性的机制之一,它是由32位序号和32位确认序号来保证的。

TCP是面向字节流的,它会为每个字节的数据都进行了编号,即序列号:

每一个ACK都带有对应的确认序列号,意思是告诉发送者,当前接收方已经收到了哪些数据,下一次发送方应该发送哪些数据。

超时重传机制

主机A发送数据给主机B之后,可能因为网络拥堵等原因,导致数据无法到达主机B。如果主机A在一个特定时间间隔内没有收到主机B发来的确认应答,就会进行数据重传,这就是超时重传机制。

如果主机A也没有收到来自主机B的确认应答,也可能是因为ACK丢失了。

当ACK发生丢包时,由于存在超时重传机制,主机B就会收到重复的数据,此时主机B就会意识到自己发送的确认应答有可能发生了丢包,导致主机A没有收到,因此就会重新发送确认应答,并且主机B会根据其前面接收到的数据的序号,丢弃掉重复的数据。


那么超时重传的时间该如何设定呢?


最理想的情况下,找到一个最小的时间,保证确认应答一定能在这个时间内返回。但是这个时间的长短,随着网络环境的不同,而存在差异。如果超时时间设的太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁发送重复的包。


TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间:


  • Linux中(Windows也是如此),超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
  • 如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。
  • 如果仍然得不到应答,等待 4*500ms 进行重传,依次类推,以指数形式递增。
  • 当累计到一定的重传次数,TCP就会认为网络或者对端主机出现异常,最后强制关闭连接。

连接管理机制

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接,以下是TCP连接到断开的全部过程:


三次握手

客户端与服务端建立连接的过程称为三次握手。

当客户端要与服务端之间相互通信时,首先就需要建立连接,此时客户端会主动向服务器发送建立连接的请求,然后双方实现三次握手。


第一次握手:客户的给服务端发送SYN报文,初始序列号为x,并且需要消耗应该序号。此时客户端进入SYN_SENT状态。当SYN=1,而ACK=0时,表明这是一个请求连接的报文。注意SYN=1时的报文不能携带数据,因此第一次握手和第二次握手都不会携带数据。因为如果携带数据的话,假如有人想要攻击服务器,只需要每次第一次握手时在SYN报文中携带大量的数据,导致服务器花费大量的缓冲区,造成服务器的崩溃。


通过第一次握手服务器可以知道:客户端发送数据的能力,以及以及自己的接受能力都处于正常状态。


第二次握手:服务端接收到了来的客户端的SYN报文后,对其进行确认,并且会把自己的SYN响应给对方,此时标志位ACK=1就是对第一次握手的报文进行的确认,并且ack = seq + 1,即为x + 1,初始序列号为y。此时服务器进入SYN_RECV状态。


通过第二次握手客户端能够知道:服务端的接收和发送能力正常,客户端自己的发送和接收能力也正常。但是服务器不知道客户端的接收能力是否正常,因此就需要进行第三次握手。


第三次握手:客户端收到了服务端的SYN+ACK数据包,此时客户端就会认为自己和服务端都愿意进行连接,因此客户端会进入ESTABLISHED状态,并且会给服务端发送一个ACK报文,表示自己收到了来自服务端的SYN+ACK响应。此时确认序号ack = y + 1,发送给服务器的第二个报文段的seq = x + 1。


通过第三次握手服务端就能够知道:客户端的接收能力以及自己的发送能力都正常,此时双方建立连接成功,可以进行网络通信了。


为什么是三次握手,而不是其他的握手次数呢?

假如是两次握手,举个打电话的例子:


  • 假如在半夜你有一个重要的事情要告诉你的对象,于是打了一个电话,打通了过后,你向电话里面说:“喂,你听得到我说话吗?我有事跟你说。"
  • 对方:“你有毛病啊,大半夜打什么电话,有什么屁快放。”,此时却从电话里面再也听不到你的消息,非常生气,以为你大半夜搞恶作剧呢,便把你拉黑了。

其实可能是你对象麦克风或者网络的原因,导致自己听不到对方说话,引起误会。客户端和服务端之间也是如此,如果只有两次握手的话,服务端就不知道客户端的接收能力以及自己发送数据的能力,所以还需要进行第三次握手才行。

【计算机网络】传输层TCP协议2:https://developer.aliyun.com/article/1383987

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
3月前
|
数据采集 算法 数据挖掘
模块化控制协议(MCP)在网络中增强智能体执行效率的研究
随着Web3技术的迅速发展,去中心化应用和智能体在各种领域的应用逐渐增多。MCP(Modularized Control Protocol,模块化控制协议)作为一种增强智能体执行能力的关键技术,为Web3场景中的智能体提供了更强的灵活性和可扩展性。本文将探讨如何利用MCP技术提升智能体在Web3场景中的执行能力,并通过实例代码展示其实现路径。
282 22
|
19天前
|
监控 负载均衡 安全
WebSocket网络编程深度实践:从协议原理到生产级应用
蒋星熠Jaxonic,技术宇宙中的星际旅人,以代码为舟、算法为帆,探索实时通信的无限可能。本文深入解析WebSocket协议原理、工程实践与架构设计,涵盖握手机制、心跳保活、集群部署、安全防护等核心内容,结合代码示例与架构图,助你构建稳定高效的实时应用,在二进制星河中谱写极客诗篇。
WebSocket网络编程深度实践:从协议原理到生产级应用
|
1月前
|
运维 架构师 安全
二层协议透明传输:让跨域二层协议“无感穿越”多服务商网络
简介:本文详解二层协议透明传输技术,适用于企业网工、运营商及架构师,解决LLDP/LACP/BPDU跨运营商传输难题,实现端到端协议透传,提升网络韧性与运维效率。
|
5月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
159 18
|
6月前
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
204 22
|
6月前
|
网络协议 数据安全/隐私保护 网络架构
|
7月前
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
268 12
|
7月前
|
缓存 网络协议 API
掌握网络通信协议和技术:开发者指南
本文探讨了常见的网络通信协议和技术,如HTTP、SSE、GraphQL、TCP、WebSocket和Socket.IO,分析了它们的功能、优劣势及适用场景。开发者需根据应用需求选择合适的协议,以构建高效、可扩展的应用程序。同时,测试与调试工具(如Apipost)能助力开发者在不同网络环境下优化性能,提升用户体验。掌握这些协议是现代软件开发者的必备技能,对项目成功至关重要。
|
8月前
|
人工智能 自然语言处理 决策智能
智能体竟能自行组建通信网络,还能自创协议提升通信效率
《一种适用于大型语言模型网络的可扩展通信协议》提出创新协议Agora,解决多智能体系统中的“通信三难困境”,即异构性、通用性和成本问题。Agora通过标准协议、结构化数据和自然语言三种通信格式,实现高效协作,支持复杂任务自动化。演示场景显示其在预订服务和天气预报等应用中的优越性能。论文地址:https://arxiv.org/pdf/2410.11905。
255 6
|
10月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
233 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?