网络流量处理中的协议解析六: 执行器

执行器

rust 中有很多异步执行环境。但是异步执行环境有一个问题。它有"传染性",如果一个函数是异步的,那么它的所有调用者都必须是异步的。在前面的流量处理模型并不是异步的。所以为了不至于把协议解析部分的异步影响到流量处理模型,我们需要一个自己的执行器。这个执行器把异步操作封装起来,然后在流量处理模型中使用。尽量不影响使用者的习惯和模型,是一个库的修养。

rust 的执行器简单来说类似于前文所讲的c语言的状态机驱动函数。如果一个future返回了 Ready ,说明future已经完成了,需要执行下一步。如果一个future返回了 Pending ,说明future还没有完成,需要等待下一次调用。因为我们不需要复杂的异步运行时,所以这里的执行器只需要控制好future的返回值即可。代码如下:

rust 复制代码
    let waker = dummy_waker();
    let mut context = Context::from_waker(&waker);
    match Pin::as_mut(parser).poll(&mut context) {
        Poll::Ready(Ok(())) => {
            self.c2s_state = TaskState::End;
            Some(Ok(()))
        }
        Poll::Ready(Err(())) => {
            self.c2s_state = TaskState::Error;
            Some(Err(()))
        }
        Poll::Pending => None,
    }

这样,内部是异步,外部是同步。每到来一个包,执行器就执行一次future,也就是解码器。外部不需要异步操作。也就是在同步代码中可以调用执行器:

rust 复制代码
    loop {
        pkt = get_packet();
        task.run(pkt);
    }

当然,要获取解码结果。需要提前设置回调函数。解码过程中就会触发回调函数。

解码器

所有的这些工作,都是为了解码器。因为需要同时处理大量的链接,解码过程中是不能等待后续数据包的。所以解码器是一个future,也就是异步函数。当后续数据还没有到来时,解码器返回Pending,暂时挂起。执行器得到Pending后,不会认为这个链接的解码已经结束,而是继续处理下一个链接。

但这种异步调用的复杂性都被rust的future机制封装起来了,解码器的实现关注解码器的实现即可。完全可以按照同步的模式来写,例如SMTP协议的解码器的部分代码:

rust 复制代码
    loop {
        let (line, seq) = stm.readline_str().await?;

        if line == "\r\n" {
            return Ok((boundary, te));
        }
    }

这就是读取重组后的头部数据的过程。可以看到,它并没有关心数据没有到来的情况。如果当前的数据包并没有完整的数据,解码器中也不需要对此进行判断,和退出。它完全按照同步的过程在执行解码。直到读取到头结束为止。唯一的区别就是它的读取数据函数式一个异步函数。末尾加了await关键字。

每一个await都会触发一次future的调用。如果当前的数据包没有完整的数据,那么await会返回Pending,解码器会被挂起。执行器会继续处理下一个数据包。当数据包到来时,解码器会被唤醒,继续执行。直到读取到头结束为止。

这样,我们就可以把协议解析的工作交给执行器来处理。执行器会自动处理异步的情况。使用者只需要关注解码器的实现即可。而且解码器的过程变得简单容易理解。

从最开始的c语言中的大循环中记录状态,到c语言中用状态机驱动,再到rust的future机制,再到现在的解码器,过程越来越简单,最终我们以同步的流水账式的代码来实现了异步的解码过程。

参考: protolens@gitee protolens@github

相关推荐
智联视频超融合平台3 小时前
无人机+AI视频联网:精准狙击,让‘罪恶之花’无处藏身
人工智能·网络协议·安全·系统安全·音视频·无人机
I won.4 小时前
计算机网络 HTTP篇常见面试题总结
网络协议·计算机网络·http
搬码临时工9 小时前
无公网ip远程桌面连接不了怎么办?内网计算机让外网访问方法和问题分析
服务器·网络协议·tcp/ip·访问公司内网
无名之逆10 小时前
[特殊字符]For Speed Enthusiasts: The Ultimate Evolution of Rust HTTP Engines
开发语言·前端·后端·网络协议·http·rust
别NULL14 小时前
《TCP/IP 详解 卷1:协议》第3章:链路层
网络·网络协议·tcp/ip
SysMax17 小时前
TC/BC/OC P2P/E2E有啥区别?-PTP协议基础概念介绍
网络·网络协议·ptp
嵌入式学习菌18 小时前
TCP通信与MQTT协议的关系
网络·网络协议·tcp/ip
Hello.Reader21 小时前
基于 HTTP 的邮件认证深入解读 ngx_mail_auth_http_module
网络·网络协议·http
weixin_5412999421 小时前
Nodejs+http-server 使用 http-server 快速搭建本地图片访问服务
网络·网络协议·http
gadiaola1 天前
【计算机网络】第2章:应用层—Web and HTTP
网络·网络协议·计算机网络·http