差一点
我们就擦肩而过了
有趣
有用
有态度
前言
tcp/ip协议栈相信在大家日常开发里面,或多或少都有接触过,在单片机领域比较常用的有以下几种开源的软件协议栈:
LwIP
uC/IP
uIP
TinyTcp
也有些产品直接使用硬件协议栈,如w5500。或者是其他的一些串口转wifi模块,如经典的esp8266等。
作为软件工程师,自然重点是关注软件协议栈。但是,哪怕是上面罗列这几种轻量级的tcp/ip协议栈,源码量都是在万行以上级别的,更别说Linux系统里面动则几十上百万行tcp协议栈了。tcp/ip协议是一个非常庞大的协议族,初学者在研究它的时候,往往容易在细节里面迷失,捉不到重点来学习,更谈不上整体把握。一般学着学着就被劝退了。
笔者在职业生涯前期也从过不少单片机开发工作,对上面的几个开源tcp协议栈也略有研究,只不过这些tcp协议栈主要运行在裸机或者是RTOS下,需要依赖相应的硬件开发板。目前本人主要从事于Linux行业,恰好Linux系統现在较为流行,于是给大家分享一个tcp协议栈--level-ip。level-ip可以直接运行在Linux系统中,不需要其他额外的硬件,希望手中有Linux系统的网络爱好者不要错过它。
该tcp协议栈运行在Linux用户空间,与应用程序完全隔离。这个机制模拟了Linux内核的tcp协议栈,它们都可以为其他应用程序提供网络链接服务。比如说,它可以为curl应用程序提供抓取网页的功能。ps:这是借助Linux虚拟网卡实现的。
该tcp协议栈源码已经托管在GitHub:https://github.com/EmbedHacker/level-ip
GitHub上level-ip的README.md已经详细说明了它实现的具体功能,有兴趣的读者可以去了解一下,再决定要不要阅读本文。
level-ip架构设计
level-ip整体软件架构其实并不复杂,我们从数据的发送流程,可以轻松理解它的全部设计, 如下图所示:

下面详细给大家讲解一下,每层设计的功能
应用程序:主要使用Socket API开发的应用程序,如我们常用的NetUtils工具(curl、wget等)
level-ip:运行在Linux用户空间的tcp/ip协议栈
虚拟网卡/tun:中转站,把level-ip协议栈的数据转发给物理网卡,或者是把物理网卡的数据转发给level-ip协议栈
物理网卡:收发以太网链路上的数据
软件运行原理
有了上面对level-ip的架构把握之后,我们从最底层开始讲解软件的运行原理。这样子分析下来,我们将对软件的底层到应用都有一个深入的把握。我们也将会在代码层面上,一窥tcp协议栈的核心理论的全貌。一旦在源码级别上,调试和掌握了tcp/ip协议栈,将带来极大的满足感和成就感,这种记忆是难以磨灭的。
我们先从底层开始,一步步先把这个软件的架构了解清楚,然后尝试把它跑起来,后面我们深入学习的时候,就能边阅读代码边调试了。
一、以太网=》物理网卡
检查Linux系统上的物理网卡,至少要保证能链接外网,否则虚拟网卡也难以借助物理网卡进行外网链接。
检测以太网和物理网卡链接是否正常的方法很简单,我们直接使用ping命令,测试是否能ping同百度网址即可:
ping www.baidu.com
如果能正常ping通,我们可以继续进行下一步,结果如下图:

如果不能ping通,请自行百度/谷歌解决。
二、物理网卡=》虚拟网卡
从物理网卡到虚拟网卡之间的数据转发,我们可以通过iptables工具来设置netfilter防火墙来实现。
(2.1) 首先,我们需要安装iptables工具,使用apt命令安装即可,如下图:
sudo apt install iptables
如果是系统自带iptables工具,则无需再安装,如下图:

(2.2) 接下来我们需要Linux系统充当一个路由器,来帮助我们实现物理网卡和虚