首页 > 编程知识 正文

tcpip的传输层协议,tcp/ip传输层协议

时间:2023-05-06 09:39:16 阅读:266587 作者:1286

TCP/IP中有两个具有代表性的传输层协议,分别是TCPUDP。TCP提供可靠传输,UDP则常用来让广播和细节控制交给应用的通信传输。

先来了解UDP,比较简单:

UDP协议

UDP协议格式:

16位UDP长度: 表示整个数据报(UDP首部 + UDP数据)的最大长度校验和: 如果校验和出错,则直接丢弃该报文

UDP特点:

无连接,指代对端IP和端口号就直接进行数据传输,不需要建立连接不可靠,没有确认应答机制,没有重传机制,如果因为网络故障导致数据无法发送到对端,UDP协议层也不会给应用层返回任何错误信息面向数据报,不能够灵活的控制读写数据的次数和数量

解释一下面向数据报:
应用层交给UDP多长的报文,UDP会原样发送,既不会拆分,也不会合并。
比如,应用层交给UDP 100个字节的数据,发送端只能调用一次sendto 发送100个字节,而接收端也只能调用一次recvfrom ,接受100个字节的数据。

UDP的缓冲区:

UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作;UDP具有接收缓冲区。 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果缓冲区满了, 再到达的UDP数据就会被丢弃;

UDP是全双工的,它的socket 既能读,也能写。

这里我们有一点要注意
UDP协议格式中有一个16位UDP长度,算下来只有64K,也就是说一个UDP能传输最大长度是64K(包含UDP首部),如果传输的数据超过该值,就需要在应用层手动分包,多次发送,并在接收端手动拼装

基于UDP的应用层协议:

NFS: 网络文件系统TFTP: 简单文件传输协议DHCP: 动态主机配置协议BOOTP: 启动协议(用于无盘设备启动)DNS: 域名解析协议
当然, 也包括你自己写UDP程序时自定义的应用层协议;

老大哥来了,也是比较重要的东西。

TCP协议

TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 可以说是对“传输、发送、控制”进行“控制”的“协议”。
TCP协议段格式:

源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;32位序号/32位确认号: 后面详细讲(确认机制);4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 = 606位标志位: URG: 紧急指针是否有效ACK: 确认号是否有效PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段 16位窗口大小: 后面再说16位校验和: 发送端填充, CRC校验(循环冗余校验码). 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分.16位紧急指针: 标识哪部分数据是紧急数据;40字节头部选项: 暂时忽略;

TCP保证可靠传输依靠的具体内容

确认应答(ACK)机制

在TCP中,将每个字节都进行了编号,即为序列号。
每一个ACK都带有对应的确认序列号,意思就是告诉发送者,我已经收到了哪些数据,下次要从哪里开始发送数据。

但是如果在数据传输的时候遭遇了一些“不测”,服务器收不到数据怎么办?这又怎么来保证数据传输的可靠性呢?

我们来了解下面的机制:

超时重传机制

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

但是,问题来了,如果是主机A未收到主机B的确认应答,也可能是ACK丢失。

这时主机A会再次发送请求,主机B也因此受到很多重复数据包,这时,前面提到的每个字节都有一个序号就起了作用,我们可以利用这些序号进行去重。

那么,超时时间如何设置呢?

最理想的情况是,找到一个最小的时间,保证确认应答一定能在这个时间内返回但是这个时间的长短,是根据网络环境等环境因素影响,是有差异的这个时间太长或者太短都不合适,会影响传输的效率,因此建议选一个合适的时间,作为超时重传时间。

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

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

上面我们说TCP保证可靠性有超时重传和确认应答机制,但是这两个机制都只是一次收发一个数据段,还要等待收到ACK才会进行下一个数据段的发送,性能较差,尤其是数据往返时间较长的时候。

因此,就有了滑动窗口的概念:锁定关键字窗口,在这个理念下,确认应答不再是以每个分段,而是以更大的单位进行确认时,转发时间会大幅度的缩减。也就是说,发送端主机在发一个数据段之后不用等待ACK响应之后才发送下一个数据段,而是继续发送。

看张图理解一下:

解释一个概念:
窗口大小: 指的是无需等待ACK就可以继续发送数据的最大值。上图窗口大小就是 4个段,没个段1000字节。

解读一下上图: 在发送前四个段的时候,不需要等待任何ACK,直接发送,在发送第五段之前接收端会给发送端发送一个ACK,然后进行下一个段的传输,以此类推。

那么,他是如何保证数据是准确传输的呢?这个机制采用了大量的缓冲区,通过缓冲区来记录当前哪些数据没有应答,只有确认应答过的数据才能从缓冲区删掉

在①的状态下,如果收到一个请求序列号位2001的确认应答,那么2001之前的数据就没有必要进行重发,该部分数据了可以直接过滤掉,滑动窗口变成③的样子。

窗口控制和重发控制
在使用滑动窗口是出现数据丢失怎么办?不慌,我们有应对措施:
这里讨论 两种情况:
一:数据包已经到达,ACK丢失

这种情况下,部分ACK丢失问题并不严重,我们可以通过下一个ACK来进行确认

情况二:某个报文段直接丢失:

当一个数据段丢失的时候,接收端会一直给发送端发送1001这样的ACK,提醒发送端,我要的是1001下一个数据段如果发送端连续三次收到了同样的ACK,就会将对应的数据进行重新发送这个时候接收端接收到1001之后,再次返回的ACK就是7001(因为2001~7000,接收端其实之前就已经接收到了,** 被放到了接受操作系统内核中的接受缓冲区中** );

这种机制被称为高速重发机制,也叫快重传,比超时重传效率更高。

流量控制

接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端缓冲区被打满,这个时候如果再继续
发送数据,就会造成丢包,继而引起丢包重传等一系列连锁反应。

因此,TCP支持根据接收端的处理能力,来决定发送端的发送速度。,这个机制叫做流量控制。

接收端可以将自己的接收缓冲区大小放进TCP首部的16位窗口大小字段,通过ACK通知发送端,一次最大能够发送多大的数据窗口大小越大,说明网络吞吐量越高接收端一旦发现自己的接收缓冲区快满的时候,就会将窗口大小设置成一个更小的值发送给发送端发送端接收到这个值之后就会减慢自己的发送速度如果接收缓冲区满了,就会将窗口中设置为0,这发送端将不在发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

接收端如何把窗口大小告诉发送端呢? 回忆我们的TCP首部中, 有一个16位窗口字段, 就是存放了窗口大小信息;
那么问题来了, 16位数字最大表示65535, 那么TCP窗口最大就是65535字节么?
实际上, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是 窗口字段的值左移 M 位; 拥塞控制

虽然有了滑动窗口这个神器,能够保证高效可靠的发送大量的数据,但是,如果在刚开始就发送大量的数据,仍然会引发问题。
一般来说,我们电脑的网络都是在一个局域网情况下的,因此,可能会因为其他主机之间的通信使得网络拥堵,如果在这种情况下贸然发送大量数据,是很有可能雪上加霜的。

TCP为了防止该问题出现,在通信一开始就会通过一个** 慢启动**的算法得出的数值,对发送的数据量进行控制。

简单来说,就是发送端先发少量的数据,先探探路,摸清当前的网络拥堵状态,再决定按照多大的传输速度进行传输。

这里引入一个概念叫做拥塞窗口

发送开始的时候,定义拥塞窗口大小为1每次收到一个ACK时,窗口大小+1;每次发送数据包的时候,将拥塞窗口和接收端反馈的窗口大小做比较,去较小值作为实际发送的窗口。

像这样的增长,是指数级别的,因此这样的启动叫做慢启动,快增长
但是如果一直这样增长下去肯定会出问题,因此还有机制来控制拥塞窗口:

这里引入一个叫做慢启动的阈值当拥塞窗口超过这个阈值的时候,不在按照指数增长而是按照线性方式增长
当TCP开始启动的时候,慢启动阈值等于窗口最大值(图中演示的是24);在每次超时重传的时候,慢启动阈值会将为原来的一半(这里是12),拥塞窗口大小置为 1 ; 延迟应答 --> 解决效率问题

如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小.

假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答, 返回的窗口就是500K;但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M;

时刻谨记:
窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输
效率;

那么所有的包都可以延迟应答么? 肯定也不是

数量限制: 每隔N个包就应答一次;时间限制: 超过最大延迟时间就应答一次;具体的数量和超时时间, 依操作系统不同也有差异, 一般N取2,超时时间取200ms; 捎带应答 --> 解决效率问题

简单理解就是接收端搭载了一个顺风车,将要回执给发送端的ACK顺便将自己的数据一并带回给发送端。

TCP异常:

进程终止:会释放文件描述符,仍然可以发送FIN,和正常关闭没什么区别机器重启:和进程终止情况相同机器掉电/断网:接收端认为连接还在,一旦接收端没有写入操作,接收端发现链接已经不在了,就会及逆行reset,即使没有写入操作。TCP内部也定制了一个保活定时器,会定时检测对端是否还在,如果对方不在,就主动关闭连接。 TCP总结

可靠性:

1. 校验和 2. 序列号,保证按续到达 3. 确认应答机制 4. 超时重传机制 5. 流量控制 6. 拥塞控制

提高性能:

1. 滑动窗口 2. 快速重传 3. 延迟应答 4. 捎带应答

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。