我们在网络中传输的数据是需要分包,分片传输的,那么发送,接收是否都可以保证数据是有序发送,有序接收,读取到的数据也都是有序的呢?
数据从生成到读取的过程
发送的过程
生成--应用层
数据当然是通过应用层的协议(代码)生成的,那么应用层的数据生成需要发送的数据之后,将这些数据存储在哪呢?
调用socket库接口,触发协议栈,进行数据发送。
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
TCP层
协议栈首先被触发的就是TCP层,也就是执行tcp层的协议代码。
IP层
数据链路层
物理层(网卡)
接收的过程
物理层
数据链路层
IP层
IP层如果接收到一个不完整的数据包,也就是只有数据包的几个分片,那么这些接收到的分片会被放到哪?
如果IP层接收到无序分片,怎么办?
IP层接收到一个完整的数据包,是不是就直接发送给TCP层?
标识字段
在IP头部中,有一个很重要的位,叫做ID号,也叫做”标识“字段,这个标识字段是发送是在TCP层生成的序列号,也标识了这个TCP报文段,也就是IP分片在整个数据中的前后位置。
如果IP层接收到一个完整的TCP报文段,但是这个TCP报文段之前的报文还没有接收到,这个TCP报文会被发送给TCP层吗?
TCP层
tcp如何处理乱序数据包?
也就是TCP层可以处理乱序的报文。
那么对于有序接收到的数据,接收到并解析完成之后是不是就立刻让如内核的接收缓冲区,等待I/O监测了?
是的。
如果是接收到一个解析之后就让应用层读取,会不会出现页面显示中,显示一个报文的数据,但是下一个数据还没到,停了一会,再接收到之后,再显示的问题?就是卡顿显示的问题。
应用层不会接收到一个包就显示一个包的数据,而是需要判断隐藏发送的数据是否都成功接收,成功接收完成所有的数据,才会显示数据。
TCP层接收到的数据放在哪里?
tcp接收到有序的数据包,解析之后,放入内核缓冲区(接收缓冲区),等待应用层读取,应用层读取缓冲区中的数据之后,这部分数据就会被从缓冲区清除。
应用层
从内核读取接收到的数据:
ssize_t recv(int socket, void *buf, size_t len, int flags)
应用层如何判断所有数据已经到达
http
http1.0
使用短连接,连接正常断开,则数据通信结束,接收到多少数据,发送的就是多少数据。
http1.1
http中有一个头部字段content_length,这个字段标识了发送端发送的所有http消息体的数据的大小,单位为字节。
应用层是通过在从内核缓冲区读取数据之后,并不会立刻获取的这部分数据,而是通过content_length字段的大小对比所有获取的数据,如果已经获取所有的数据,才会应用(比如显示)数据,否则缓存获取的数据。
(这只是http判断数据结束的方式之一)