手写用户态协议栈,udpipeth数据包的封装,零拷贝的实现

目录;文章不重要,总结重要有福利哦

1. udp/ip/eth数据包的封装,

2. 零拷贝的实现,

3. 柔性数组

1.什么是TCP/IP

TCP/IP是一套用于网络通信的协议集合或者系统。TCP/IP协议模型就有OSI模型分为7层。但其实一般我们所谈到的都是四层的TCP/IP协议栈。


网络接口层:主要是指一些物理层层次的接口,比如电缆等

网络层:提供了独立于硬件的逻辑寻址,实现物理地址和逻辑地址的转换。网络层协议包括IP协议(网际协议),ICMP协议(互联网控制报文协议),IGMP协议(Internet组协议管理)

传输层:为网络提供了流量控制,错误控制和确认服务。传输层有两个互不相同的传输协议:TCP(传输控制协议)、UDP(用户数据报协议)

应用层:为文件传输,网络排错和Internet操作提供具体的程序应用

2.数据包

在TCP/IP协议中数据由上至下将数据封装成包,然后再由下至上的拆包。那么数据又是怎么打包的呢?

在装包的时候,每一层都会增加一些信息用于传输,这部分信息叫做报头。当上层数据到达本层的时候,会将数据加上报头打包在一起形成新的数据包继续往下一层传递。拆包的时候就是反着来了,就像俄罗斯套娃一样,拆完最外面一层得到需要的报头,向上传递。

零拷贝实现原理

内容拷贝过程

场景:从一个文件中读出并将数据传到另一台服务器实现伪代码如下:

File.read(file, buf, len); Socket.send(socket, buf, len); // 此过程涉及4次拷贝

NIO优化

在整个过程中,过程1和4是由DMA负责(类似通道Channel),并不会消耗CPU,只有过程2和3的拷贝需要CPU参与,可以直接把内核态读取缓冲区直接拷贝到套接字相关的缓冲区,优化如下图

实现方式:FileChannel的tansferTo()方法可是实现,将数据从文件通道传输到给定的可写字节的通道,替换file.read() 方法和 socket.send()方法

//获取缓冲区
Buffer buffer=ByteBuffer.allocateDirect(1024);
//获取文件通道
FileChannel fileChannel = 
FileChannel.open(Paths.get(System.getProperty("user.dir")  "/assets/file.txt"), StandardOpenOption.READ);
//获取socket通道
SocketChannel socketChannel=SocketChannel.open();
//将文件通道转到socket通道
fileChannel.transferTo(buffer.position(),buffer.limit(),socketChannel);


经过上述优化后后

  • 上下文切换的次数从四次减少到了两次
  • 数据拷贝次数从四次减少到了三次(其中DMA copy 2次,CPU copy 1次)

零拷贝的实现

Linux内核2.4及后期版本中,针对套接字缓冲区描述符做了调整,DMA自带了收集功能,内部操作发生了改变,用户使用不变,内部操作如下图:

总结;详细教程关注+后台私信;资料;两个字可以免费领取 资料内容包括:C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,嵌入式 等。。

相关文章

《Nginx 全功能应用大揭秘:十大场景示例详解》

Nginx 全场景应用:示例与解析在现代互联网架构中,Nginx 凭借其高性能、高并发处理能力以及丰富的功能特性,成为了不可或缺的基础设施组件。下面将详细介绍 Nginx 的各种应用场景,并给出对应的...

面试问到UDP,这样回答offer拿到手软

UDP协议,作为一个面试互联网公司几乎必问的题目,你真的有回答好吗?请你讲一下什么是UDP。请你说一下TCP和UDP的区别。请你说下UDP在哪些场景用到。请你说下UDP的特性。请你......(求求你...

开源推荐#7:Nginx 配置太复杂?试试这个可视化面板

大家好,我是 jonssonyan。Nginx 作为高性能的 Web 服务器和反向代理,在全球范围内被广泛使用。它功能强大、性能卓越,但对于不少开发者和运维人员来说,其基于文本的配置文件(.conf)...

(干货)Docker 快速入门,对比KVM有什么区别?如何安装与配置?

Docker优势说明更快的交付和部署使用docker 开发人员可以使用镜像来快速构建一套标准的开发环境;开发完成之后,测试和运维人员可以直接使用完全相同的环境来部署代码,只要开发测试过的代码,就可以确...

Linux C Socket UDP编程详解及实例分享

1、UDP网络编程主要流程UDP协议的程序设计框架,客户端和服务器之间的差别在于服务器必须使用bind()函数来绑定侦听的本地UDP端口,而客户端则可以不进行绑定,直接发送到服务器地址的某个端口地址。...

linux网络编程之socket:基于UDP协议的网络程序

一、下图是典型的UDP客户端/服务器通讯过程下面依照通信流程,我们来实现一个UDP回射客户/服务器ssize_t send(int sockfd, const void *buf, size_t le...