- 操作系统
- 云原生
- 虚拟化
- 网络
【免费下载链接】IncludeOS
A minimal, resource efficient unikernel for cloud services
本指南以test/integration/net/tcp/目录下的 TCP 集成测试为线索,系统讲解如何在 IncludeOS unikernel 中构建、启动一个 TCP 测试服务,并用宿主机 Python 脚本对 TCP 栈进行端到端验证。读完本文,你将掌握该测试的完整运行方式(含 VirtualBox NAT 端口转发配置)、六组测试用例各自验证的 TCP 能力,以及 IncludeOS 的 TCP API、连接状态机与相关源码实现细节。
一、测试概览与目录结构
IncludeOS 的 TCP 集成测试位于仓库的 test/integration/net/tcp 目录,采用"unikernel 服务端 + 宿主机 Python 客户端"的双端结构:
| 文件 | 角色 |
|---|---|
| service.cpp | IncludeOS unikernel 内的 TCP 测试服务,编译为net_tcp.elf.bin |
| test.py | 宿主机 Python 测试脚本,通过 vmrunner 驱动虚拟机并充当 TCP 对端 |
| debug.py | 面向 IPv4 的简化调试脚本(Python 2 风格),用于快速手工验证 |
| vm.json | 虚拟机配置:virtio 网卡、固定 MAC、256 MiB 内存 |
| CMakeLists.txt | 测试服务的 CMake 构建脚本 |
| linux/ | 在 Linux 用户态(非 unikernel)运行同一测试的配置与脚本 |
该测试覆盖了 TCP 栈的多项核心能力:监听与连接分配、小/中/大三种规模的收发、TCP 状态机迁移(含主动关闭的完整流程)、资源释放,以及出站 Internet 连接。
二、快速开始:两行命令跑通测试
根据 README 的说明,测试分两步执行:
# 1. 启动 TCP 测试服务(构建并启动 IncludeOS 虚拟机镜像) ./test.sh # 2. 在宿主机运行 Python 测试端 python test.py $GUEST_IP $HOST_IP其中$GUEST_IP与$HOST_IP均为可选参数,默认值分别为GUEST=10.0.0.42、HOST=10.0.0.1。脚本的作用是在服务运行期间,从宿主机发起真实的 TCP 连接来验证 IncludeOS TCP 栈的收发行为。
需要特别说明的是,README 中标注的默认地址10.0.0.42与实际源码 service.cpp 中配置的10.0.0.44略有出入——服务端通过network_config()将 unikernel 的 IPv4 地址设置为10.0.0.44,并配置网关10.0.0.1、DNS8.8.8.8。因此实际联调时,客户端应使用10.0.0.44作为 GUEST 地址(可参考 debug.py 中的默认值)。
若要让 unikernel 发起出站 Internet 连接,必须在宿主/网关上设置正确的转发规则,详见下文「出站连接与网络配置」。
三、双端联动机制:vmrunner 事件驱动的测试编排
这套测试的精髓在于 test.py 与虚拟机之间的输出触发(on_output)协作:unikernel 内的服务在完成某个阶段的准备后打印标记文本,Python 脚本捕获到该输出即执行对应的连接测试。
# Get an auto-created VM from the vmrunner vm = vmrunner.vms[0] # Add custom event-handler vm.on_output("TEST1", test1) vm.on_output("TEST2", test2) vm.on_output("TEST3", test3) vm.on_output("TEST4", test4) vm.on_output("TEST5", test5) if len(sys.argv) > 1: vm.boot(image_name=str(sys.argv[1])) else: # Boot the VM, taking a timeout as parameter vm.boot(120, image_name='net_tcp.elf.bin')脚本默认启动镜像net_tcp.elf.bin,超时 120 秒。端口与测试阶段的对应关系定义在脚本头部:
TEST1 = 8081 TEST2 = 8082 TEST3 = 8083 TEST4 = 8084 TEST5 = 8085同时,service.cpp 中定义了包含 8080 在内的六组端口:
tcp::port_t TEST0{8080},TEST1{8081}, TEST2{8082}, TEST3{8083}, TEST4{8084}, TEST5{8085};端口 8080 用于 Test 0 的"回显"压力验证,8081~8085 则分别对应 Python 脚本的test1~test5回调。
虚拟机的两种角色:client 与 server
Python 脚本中的connect()与listen()分别模拟 TCP 客户端与服务端:
- connect():向 GUEST 的指定端口发起连接,进入循环
recv(1024)后sendall(data)原样回传,从而验证"服务端发送、客户端接收、客户端回传"的完整数据路径; - listen():绑定 HOST 的端口等待连接,收到数据后回传并关闭连接——这是为了验证 unikernel 的出站连接能力(即 unikernel 主动
connect到宿主机)。
有趣的是,脚本中 GUEST 与 HOST 的默认值使用了 IPv6 链路本地地址(fe80:...%bridge43),说明这套测试在 vmbuild/vmrunner 的标准桥接网络(bridge43)下同时覆盖 IPv4 与 IPv6 场景。
四、构建配置与虚拟机规格
CMakeLists.txt 揭示了镜像的构建方式:
project (service) include(os) set(SOURCES service.cpp ) os_add_executable(net_tcp "TCP test" ${SOURCES}) os_add_drivers(net_tcp virtionet e1000 vmxnet3) os_add_stdout(net_tcp default_stdout) configure_file(test.py ${CMAKE_CURRENT_BINARY_DIR})os_add_executable(net_tcp ...)生成名为net_tcp的 unikernel 可执行镜像;os_add_drivers同时注册了 virtio-net、e1000、vmxnet3 三类网卡驱动,使其能适配不同虚拟化平台;configure_file(test.py ...)会把测试脚本复制到构建输出目录,方便与镜像一同交付。
虚拟机本身在 vm.json 中定义:
{ "net" : [{"device" : "virtio", "mac" : "c0:01:0a:00:00:2a"}], "mem" : 256 }即:一块 virtio 网卡(固定 MACc0:01:0a:00:00:2a)、256 MiB 内存。该 MAC 以c0:01:0a开头,对应 IPv4 链路10.0.x.x段的常规分配规律。
五、六组测试用例深度解析
5.1 测试数据构造
service.cpp 在Service::start()中构造了三种规模的测试负载:
std::string small, big, huge; int S{150}, B{1500}, H{150000}; std::string TEST_STR {"Kappa!"}; // Default MSL is 30s. Timeout 2*MSL. // To reduce test duration, lower MSL to 3s. milliseconds MSL_TEST = 3s;- small:150 个
"Kappa!"拼接(约 1 KB 级); - big:以
"start-"开头、"-end"结尾,中间拼接 1500 个递增数字(约 10 KB 级); - huge:150000 个
"Kappa!"拼接(约 1.2 MB 级),用于验证 TCP 在大数据量下的分片、重组与滑动窗口行为。
同时将 MSL(最大报文段生存期)从默认的 30 秒下调为 3 秒,以缩短 TIME-WAIT 阶段的测试等待时间——因为连接关闭后需要等待2 × MSL才能确认资源被完全释放。
5.2 Test 0:8080 端口回显压力验证("Circle of Evil")
// Trigger with e.g.: // dd if=/dev/zero bs=9000 count=1000000 | nc 10.0.0.44 8080 | grep Received -a tcp.listen(TEST0).on_connect([](tcp::Connection_ptr conn) { INFO("Test 0", "Circle of Evil"); conn->on_read(424242, conn { recv += buffer->size(); chunks++; if (chunks % 100 == 0) { std::string res = std::string("Received ") + util::Byte_r(recv).to_string() + "\n"; printf("%s", res.c_str()); auto new_buf = std::make_shared<std::pmr::vector<uint8_t>>(res.begin(), res.end()); conn->write(new_buf); } conn->write(buffer); }); });该用例在连接建立后注册一个容量高达 424242 字节的读请求,收到多少数据就原样写回多少(回显),每累计 100 个数据块打印一次累计接收量。注释中的命令展示了如何手工触发压力测试:
dd if=/dev/zero bs=9000 count=1000000 | nc 10.0.0.44 8080 | grep Received -a5.3 Test 1:小字符串精确收发
tcp.listen(TEST1).on_connect([](tcp::Connection_ptr conn) { INFO("Test 1", "SMALL string (%u)", small.size()); conn->on_read(small.size(), conn { CHECKSERT(std::string((char*)buffer->data(), buffer->size()) == small, "Received SMALL"); INFO("Test 1", "Succeeded, TEST2"); conn->close(); }); conn->write(small); });连接建立后,服务端立即写入small字符串,并注册一个容量恰好等于small.size()的读请求。只有当接收到的内容与small完全一致时,CHECKSERT断言才会通过,随后关闭连接。
5.4 Test 2:大字符串累积校验
tcp.listen(TEST2).on_connect([](tcp::Connection_ptr conn) { INFO("Test 2", "BIG string (%u)", big.size()); auto response = std::make_shared<std::string>(); conn->on_read(big.size(), [response, conn] (tcp::buffer_t buffer) { response->append(std::string{(char*)buffer->data(), buffer->size()}); if(response->size() == big.size()) { CHECKSERT((*response == big), "Received BIG"); INFO("Test 2", "Succeeded, TEST3"); conn->close(); } }); conn->write(big.data(), big.size()); });由于big超过单个 TCP 段的承载能力,数据会被拆分为多个段到达。服务端利用on_read(big.size(), ...)让回调累积拼接,直到总长度等于big.size()才进行内容比对——这直接验证了 TCP 流的按序重组能力。
5.5 Test 3:超大字符串分块收发
tcp.listen(TEST3).on_connect([](tcp::Connection_ptr conn) { INFO("Test 3", "HUGE string (%u)", huge.size()); auto temp = std::make_shared<Buffer>(huge.size()); conn->on_read(16384, [temp, conn] (tcp::buffer_t buffer) { memcpy(temp->data + temp->written, buffer->data(), buffer->size()); temp->written += buffer->size(); // when all expected data is read if(temp->written == huge.size()) { bool OK = (temp->str() == huge); CHECKSERT(OK, "Received HUGE"); INFO("Test 3", "Succeeded, TEST4"); } }); auto half = huge.size() / 2; conn->on_write(half { CHECKSERT(n == half, "Wrote half HUGE (%lu bytes)", n); }); conn->write(huge.data(), half); conn->write(huge.data()+half, half); conn->close(); });该用例同时验证发送与接收两个方向:发送侧把huge拆成两半写入(并通过on_write校验每半恰好发送half字节);接收侧用on_read(16384, ...)以 16 KiB 的粒度分块收集,全部到位后整体比对。Buffer结构(written、read、data、size)跟踪写入进度,是对大流量场景下 TCP 收发一致性的强校验。
5.6 Test 4:连接状态机与主动关闭
这是全测试中对TCP 状态机验证最深入的一组:
tcp.listen(TEST4).on_connect([](tcp::Connection_ptr conn) { INFO("Test 4","Connection/TCP state"); // There should be at least one connection. CHECKSERT(stack().tcp().active_connections() > 0, "There is (>0) open connection(s)"); // Test if connected. CHECKSERT(conn->is_connected(), "Is connected"); // Test if writable. CHECKSERT(conn->is_writable(), "Is writable"); // Test if state is ESTABLISHED. CHECKSERT(conn->is_state({"ESTABLISHED"}), "State: ESTABLISHED"); INFO("Test 4", "Active close"); CHECKSERT(!conn->is_closing(), "Is NOT closing"); // Setup on_disconnect event conn->on_disconnect([](auto conn, tcp::Connection::Disconnect) { CHECKSERT(conn->is_closing(), "Is closing"); CHECKSERT(conn->is_state({"FIN-WAIT-2"}), "State: FIN-WAIT-2"); Timers::oneshot(1s, [conn] (auto) { CHECKSERT(conn->is_state({"TIME-WAIT"}), "State: TIME-WAIT"); INFO("Test 4", "Succeeded. Trigger TEST5"); OUTGOING_TEST({gateway, TEST5}); }); Timers::oneshot(5s, [] (Timers::id_t) { FINISH_TEST(); }); }); // Test for active close. conn->close(); CHECKSERT(!conn->is_writable(), "Is NOT writable"); CHECKSERT(conn->is_state({"FIN-WAIT-1"}), "State: FIN-WAIT-1"); });验证路径非常清晰:
- 连接建立后必须处于ESTABLISHED状态,且
is_connected()、is_writable()为真; - 调用
conn->close()发起主动关闭,立即断言进入FIN-WAIT-1且不可写; - 收到对端 ACK 后迁移到FIN-WAIT-2;
- 1 秒后断言进入TIME-WAIT;
- 此时通过
OUTGOING_TEST({gateway, TEST5})触发下一阶段——unikernel 主动向网关(IPv6 链路本地地址)的 8085 端口发起出站连接; - 5 秒后调用
FINISH_TEST()进入收尾校验。
5.7 出站连接与资源释放收尾
FINISH_TEST()是整套测试的终点:
void FINISH_TEST() { INFO("TEST", "Started 2 x MSL + 100ms timeout."); Timers::oneshot(2 * MSL_TEST + 100ms, [] (Timers::id_t) { INFO("TEST", "Verify release of resources"); CHECKSERT(stack().tcp().active_connections() == 0, "No (0) active connections"); printf("# TEST SUCCESS #\n"); }); }它等待2 × MSL + 100ms(MSL 已从默认 30s 降为 3s,因此约 6.1 秒),然后断言active_connections() == 0,证明所有连接及其占用的资源(读缓冲、写队列、端口绑定)都已随 TIME-WAIT 结束而彻底释放。# TEST SUCCESS #是整套测试成功的最终标志。
出站连接的代码路径在OUTGOING_TEST()与OUTGOING_TEST_INTERNET()中体现:
void OUTGOING_TEST(Socket outgoing) { INFO("TEST", "Outgoing Connection (%s)", outgoing.to_string().c_str()); stack().tcp().connect(outgoing, [](tcp::Connection_ptr conn) { CHECKSERT(conn != nullptr, "Connection successfully established."); conn->on_read(small.size(), ...); conn->write(small); conn->on_disconnect([](tcp::Connection_ptr conn, tcp::Connection::Disconnect) { CHECK(true, "Connection closed by server"); CHECKSERT(conn->is_state({"CLOSE-WAIT"}), "State: CLOSE-WAIT"); conn->close(); }) .on_close([]{ OUTGOING_TEST_INTERNET(TEST_ADDR_TIME); }); }); }当 unikernel 主动发起连接后,对方(Python 脚本的listen(TEST5))会接收、回传并关闭连接,此时 unikernel 侧应进入CLOSE-WAIT;随后on_close回调触发最后一步——OUTGOING_TEST_INTERNET(TEST_ADDR_TIME)尝试解析并连接真实外网主机india.colorado.edu:13(daytime 服务),完成对 DNS 解析与外部连接能力的验证。
六、TCP 状态机与 API 的源码级验证
测试中反复出现的is_state({"ESTABLISHED"})、FIN-WAIT-1、CLOSE-WAIT、TIME-WAIT等状态,全部定义在 connection_states.hpp 中。IncludeOS 的 TCP 连接状态机完整实现了 RFC 793 定义的全部状态:
| 状态 | 定义位置 | 测试覆盖点 |
|---|---|---|
| CLOSED | connection_states.hpp | 资源释放后的最终态(Test 收尾) |
| LISTENING | connection_states.hpp | 服务端监听(tcp.listen) |
| SYN-SENT | connection_states.hpp | 出站连接建立(Test 5) |
| SYN-RCV | connection_states.hpp | 被动打开的三次握手中间态 |
| ESTABLISHED | connection_states.hpp | Test 4 的核心断言 |
| FIN-WAIT-1 / FIN-WAIT-2 | connection_states.hpp | Test 4 主动关闭路径 |
| CLOSE-WAIT | connection_states.hpp | Test 5 对端先关闭场景 |
| CLOSING / LAST-ACK / TIME-WAIT | connection_states.hpp | Test 4 的 TIME-WAIT 断言 |
状态的判定通过is_state()实现——它既支持按状态对象比较(is_state(const State&)),也支持按字符串比较(connection.hpp),后者正是测试中conn->is_state({"ESTABLISHED"})的调用方式。
TCP 可调参数与测试中的运用
TCP 类的公开 API 提供了丰富的协议参数,测试用到了其中两个,其余可在实际服务中按需配置:
| API | 测试中的用法 | 说明 |
|---|---|---|
set_MSL(ms) | tcp.set_MSL(3s) | 设置最大报文段生存期,决定 TIME-WAIT 时长(连接在 2×MSL 后关闭) |
set_total_bufsize(bytes) | tcp.set_total_bufsize(64_MiB) | 限制 TCP 层可用的总内存池上限,防止大数据测试耗尽内存 |
listen(port) | 8080~8084 | 绑定端口开始监听,返回Listener& |
connect(socket) | Test 5 | 发起出站连接,可附带ConnectCallback |
set_window_size(wsize, factor) | — | 设置通告窗口(可配窗口缩放因子,因子最大 14,对应 RFC 7323) |
set_DACK(timeout) | — | 延迟 ACK 超时(RFC 1122) |
set_SACK(bool) | — | 选择性确认开关(RFC 2018) |
set_max_syn_backlog(n) | — | SYN 队列最大积压 |
set_min/max_bufsize | — | 缓冲区大小范围(须为 2 的幂) |
其中set_MSL与set_total_bufsize在 service.cpp 中的调用如下:
auto& tcp = inet.tcp(); // reduce test duration tcp.set_MSL(MSL_TEST); // Modify total buffers assigned to TCP here tcp.set_total_bufsize(64_MiB);从源码看,set_total_bufsize最终会同步到 TCP 内部的内存池mempool_(tcp.hpp),所有连接的读写缓冲都由该池分配。此外,连接对象的 TCB(Transmission Control Block) 完整保存了 RFC 793 定义的发送序列变量(SND.UNA/SND.NXT/SND.WND)、接收序列变量(RCV.NXT/RCV.WND)以及拥塞控制变量(cwnd、ssthresh),并实现了 New Reno 快速恢复(RFC 6582)、Limited Transmit(RFC 3042)等拥塞控制机制。测试中 424242 字节的读缓冲与huge字符串的分块收发,正是对这些机制的实战压测。
连接事件回调模型
测试大量使用事件回调,这些回调定义于 connection.hpp:
on_connect(cb):连接建立时触发;出站连接失败时回调参数为nullptr(L68-L80);on_read(recv_bufsz, cb):当收到PSH(PUSH)标志或接收缓冲已满时触发,recv_bufsz决定读缓冲大小(L82-L94);on_disconnect(cb):对端发送 FIN(表示想关闭)或收到 RST(连接被重置)时触发,回调携带Disconnect原因(CLOSING/REFUSED/RESET),默认行为是本地也关闭连接(L125-L139);on_close(cb):连接彻底关闭后触发,此后连接对象不可再用,适合清理连接副本(L141-L153);on_write(cb):一次写请求发送完成后触发,仅代表数据已发出而非对端已收到(L155-L168)。
Test 4 的on_disconnect链式用法(.on_close([]{ OUTGOING_TEST_INTERNET(TEST_ADDR_TIME); }))展示了如何利用事件编排多阶段测试流程。
七、VirtualBox 环境实操(README 原始配方)
README 特别提供了在 OS X + VirtualBox 上运行该测试的完整配方,适用于没有 vmrunner 桥接环境的读者。完整步骤如下:
- 构建镜像:执行
make(注意先导出LD_INC与AR_INC环境变量); - 启动虚拟机:
/<includeos_repo>/etc/vboxrun.sh IncludeOS_TCP_Test.img TCP_test(实际镜像名以构建产物为准,例如
net_tcp.elf.bin) - 关闭虚拟机:测试结束后 Kill VM;
- 打开 VirtualBox 网络设置:
Virtualbox => TCP_test => Settings => Network; - 将 Adapter 1 改为 NAT:进入
Advanced => Port Forwarding,添加端口转发规则; - 添加以下端口转发规则:
$ vboxmanage showvminfo TCP_test ... NIC 1 Rule(0): name = Rule 1, protocol = tcp, host ip = 127.0.0.1, host port = 8081, guest ip = , guest port = 8081 NIC 1 Rule(1): name = Rule 2, protocol = tcp, host ip = 127.0.0.1, host port = 8082, guest ip = , guest port = 8082 NIC 1 Rule(2): name = Rule 3, protocol = tcp, host ip = 127.0.0.1, host port = 8083, guest ip = , guest port = 8083 NIC 1 Rule(3): name = Rule 4, protocol = tcp, host ip = 127.0.0.1, host port = 8084, guest ip = , guest port = 8084即把宿主机的 8081~8084 端口分别转发到虚拟机的同名端口(对应 Test 1~Test 4)。随后重新启动虚拟机(重复步骤 2),由于 NAT 转发已经生效,即可在宿主机用回环地址直接验证:
$ python test.py 127.0.0.1 127.0.0.1注意:NAT 端口转发规则只覆盖 8081~8084;Test 0(8080 回显压力测试)与 Test 5(出站连接,需要 HOST 侧监听 8085)如需验证,可参照同样方式补充转发规则。
八、出站连接与网络配置
README 明确指出:"To make outgoing internet connection work, correct forwarding rules needs to be setup."(要使出站 Internet 连接可用,必须设置正确的转发规则。)
服务端在启动时通过 Inet::network_config 完成 IPv4 网络配置:
inet.network_config( { 10, 0, 0, 44 }, // IP { 255,255,255, 0 }, // Netmask { 10, 0, 0, 1 }, // Gateway { 8, 8, 8, 8 } // DNS ); inet.add_addr({"fe80::e823:fcff:fef4:85bd"}, 64); static ip6::Addr gateway{"fe80::e823:fcff:fef4:83e7"};同时配置了 IPv6 链路本地地址与网关。测试流程中,OUTGOING_TEST_INTERNET依赖stack().resolve(host, callback)进行 DNS 解析(此处解析india.colorado.edu),再对解析出的地址发起connect。要让这一步在 NAT/桥接网络下真正成功,宿主机需开启相应的地址转换与转发(如 iptables MASQUERADE 或 VirtualBox NAT 的端口转发),这也正是 README 强调转发规则的用意所在。
此外,在 Linux 用户态(USERSPACE_LINUX)构建时,service.cpp 会先创建虚拟网络设备:
#ifdef USERSPACE_LINUX extern void create_network_device(int N, const char* route, const char* ip); create_network_device(0, "10.0.0.0/24", "10.0.0.1"); #endif九、Linux 用户态运行模式
除了在虚拟机中运行,同一份 service.cpp 还可以编译为 Linux 用户态程序(省去虚拟化开销,便于调试)。linux/run.sh 的流程是:
- 编译并安装 IncludeOS 的 Linux 用户态库(
$INCLUDEOS_SRC/linux/build,可用num_jobs控制并行度,默认-j32); - 在本目录
build/下用linux.service.cmake(见 cmake/linux.service.cmake)构建测试服务; - 以
sudo运行产物二进制(需要创建/dev/net/tap之类的 tun/tap 设备)。
对应的 linux/CMakeLists.txt 将服务命名为tcp_test,并复用上一级的../service.cpp作为唯一源码。
十、集成到自动化测试框架
该测试已接入仓库的 CI 冒烟测试。在 test/test.sh 中,smoke_tests()将test/integration/net/tcp列为关键冒烟用例之一:
smoke_tests(){ nix-shell ./unikernel.nix $CCACHE_FLAG --argstr unikernel ${INTEGRATION_TESTS}/net/udp --arg doCheck true nix-shell ./unikernel.nix $CCACHE_FLAG --argstr unikernel ${INTEGRATION_TESTS}/net/tcp --arg doCheck true nix-build ./unikernel.nix $CCACHE_FLAG --argstr unikernel ${INTEGRATION_TESTS}/memory/paging --arg doCheck true nix-build ./unikernel.nix $CCACHE_FLAG --argstr unikernel ${INTEGRATION_TESTS}/kernel/smp --arg doCheck true }同时,test.sh 将net/tcp列入unsandbox_list——因为该测试需要创建 tun 设备与网桥(bridge43),在沙箱环境中会报错failed to create tun device: Operation not permitted,因此必须以非沙箱方式运行。
测试断言使用 IncludeOS 提供的CHECK/CHECKSERT宏(定义于 api/info):
#define CHECK(TEST, TEXT, ...) kprintf("%16s[%s] " TEXT "\n","", TEST ? "x" : " ", ##__VA_ARGS__) #define CHECKSERT(TEST, TEXT, ...) CHECK(TEST, TEXT, ##__VA_ARGS__), assert(TEST)CHECK:打印[x](通过)或[ ](失败)的检查项,仅用于观测;CHECKSERT:在CHECK基础上叠加assert,失败即触发断言,中止运行。
因此,# TEST SUCCESS #出现即代表从 TCP 连接建立、数据收发、状态迁移到资源释放的全部断言依次通过。
总结
IncludeOS 的 TCP 集成测试是一套麻雀虽小、五脏俱全的协议验证体系:它以 service.cpp 承载六组覆盖小、中、大、超大流量与状态机迁移的用例,以 test.py 通过 vmrunner 事件驱动完成宿主机侧的双向验证,并以 VirtualBox NAT 端口转发或 Linux 用户态模式作为补充运行环境。对开发者而言,它既是验证 TCP 栈正确性的回归测试,也是学习 IncludeOS TCP API(listen、connect、on_read、on_disconnect、set_MSL等)与 RFC 793 状态机实现的最佳示例。
- 操作系统
- 云原生
- 虚拟化
- 网络
【免费下载链接】IncludeOS
A minimal, resource efficient unikernel for cloud services
相关推荐
IncludeOS DHCP 客户端功能测试指南:从 negotiate_dhcp 调用到网桥联调验证
IncludeOS DHCP 客户端功能测试指南:从 negotiate_dhcp 调用到网桥联调验证 导读 本指南围绕 IncludeOS 仓库中的 DHCP
操作系统云原生虚拟化网络AxonHub 负载均衡集成测试完全指南:从 TESTING_GUIDE 到源码级验证
AxonHub 负载均衡集成测试完全指南:从 TESTING_GUIDE 到源码级验证 本指南以 TESTING_GUIDE.md https://link.g
AI 应用API网关LLM 网关后端前端IncludeOS 内建 DHCP 服务器测试指南:从桥接网络配置到 DHCPD 状态机源码解析
IncludeOS 内建 DHCP 服务器测试指南:从桥接网络配置到 DHCPD 状态机源码解析 本文以仓库内 test/integration/net/dhc
操作系统云原生虚拟化网络
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考