一般当协议栈接受到数据时可能并不会马上发出去,而是放在发送缓冲区中,为什么要这样做呢?
有些程序可能一次性会传所有数据,但有些程序会逐行传递,在这种情况下,如果收到数据就发送,可能会造成发送大量小包数据,导致效率低下 。至于需要积累多少数据才发送一般是根据两方面因素来考量,一个是每个网络包的数据长度,还有一个纬度是处理时间 。
网络包容纳的数据长度
首先介绍下两个名词:
MTU:一个网络包的最大长度,以太网中一般是1500字节,是包含头部的总长度 。
MSS: 除去头部后,一个网络包所有容纳的数据最大长度 。

文章插图
处理时间
当一个应用程序发送数据的频率不高时,如果每次都需要等到长度达到 MSS 才发送,就会造成等待时间过长 。为了解决这种情况,协议栈会有一个计时器,如果达到一定时间,即使还远未达到 MSS 长度,也会把网络包发送出去 。
ACK 机制确认网络包接收情况当客户端向服务端发送数据时,TCP会将数据的字节数算好写在 TCP 头部,同时会生成一个随机数 当作 ACK 一并发送给服务端,服务端接受后就会根据实际收到的长度和TCP头部给的长度做对比,来确保数据没有遗漏,同时客户端还需要告知服务端是从哪个字节开始发送的,而我们的 ACK是个随机值,这时候我们就需要通过 SYN 控制位设置为1发送给服务器,这样服务器就知道其初始是从哪个字节开始发送的 。
接受方收到数据后,如果数据没问题,就需要告知发送方收到了多少数据,也是通过 ACK 号的操作来返回的,这个 ACK 的值就是一共接收了多少字节 。

文章插图
通过这种机制,我们就可以确认接收方是否正确收到数据,如果没有准确收到,就可以重新发送网络包 。
无论网络发生何种错误,我们就都可以发现并采取补救措施 。
窗口滑动一般如果我们每发送一个网络包就等待 ACK 返回确认后再发送下一个包,这个等待 ACK 的时间啥都不做就会很浪费 。
窗口滑动的概念就是每次发送一个网络包,不会等 ACK 返回就会继续发送下一个包,减少等待时间的浪费 。

文章插图
【数据在网络中是如何传输的】但这种方式也会存在问题,假如发送方不断发送数据给接收方,接收方第一个数据还没处理完,第二个数据就来了,这些来不及处理的数据会进入接收缓冲区,数据会不断增多,就会造成溢出 。避免这种方式的处理是通过接收方告知发送方自己最大能接收多少数据,发送方会根据这个值对发送的数据进行控制 。
删除套接字当我们数据收发完成后,就会启动断开机制,以 Web 为例,收发数据结束时,服务器会发起断开过程,会调用 Socket 库的 close 程序,服务器协议栈会生成一个包含断开信息的 TCP 头部,就是将 FIN 比特设置为1 。协议栈会委托 IP 模块向客户端发送数据 。

文章插图
当客户端接收到 FIN 为 1 的 TCP 头部时,客户端协议栈会将自己的套接字标记为进入断开操作状态,然后告知服务器已经收到 FIN 为 1的包,客户端会向服务器返回一个 ACK 号 。
UDP 协议收发操作之前我们都是以 TCP 协议讲解的数据收发操作,可以看出整个流程下来其实是挺复杂的,但是有时候可能我们并不需要这么复杂的安全校验,UDP 就可以满足一些简单的数据收发 。例如像我们之前提到的 向 DNS 服务器查询 IP 地址,我们就是用的 UDP 协议 。
UDP 没有 TCP 的接收确认、窗口等机制,在收发数据之前是不需要进行交换控制信息,不需要进行连接操作 。
接收数据也很简单,只需要根据 IP 头部中的接收方和发送方 IP 地址,以及 UDP 头部中的接收方和发送方端口号,找到对应的套接字然后将数据交给相应的应用程序即可 。

文章插图
关注小蛋,一起成长,一起进步
推荐阅读
- Android开发:使用Kotlin+协程+自定义注解+Retrofit的网络框架
- H3C和锐捷等网络设备如何查看光衰
- 电脑网络显示小地球却可以上网修复办法
- Linux服务器打造一个简单的文件共享系统
- C|数据存储地址与字节偏移、数据索引
- Windows10系统网络安装部署
- windows8笔记本连接wifi受限怎么办,笔记本无法连接无线网络
- Python爬虫实战,pyecharts模块,Python实现中国地铁数据可视化
- Mysql数据库tinyint,int,bigint,char,varchar究竟用哪个?
- 俄罗斯啤酒在中国畅销吗,玫瑰花可以和康乃馨起泡长期饮用吗功效有哪些
