局域网通讯软件:详细设计(1)

2025/3/271292 字

自从上次做完概要设计之后,就先通过问ai的方式把 数据模型这个模块做好了,代码也上传到了github

所以今天来做一下 消息接收和发送模块的详细设计

一、模块分解

首先将这个模块按照功能进一步划分为三个模块。

  1. 接收模块:负责接收用户的连接请求和消息包;
  2. 连接管理模块:负责管理用户的连接状态;
  3. 发送模块:负责向指定用户发送响应包。

二、时序图

接下来通过绘制各个功能的时序图理清各个模块之间的交互过程。

1.用户请求连接


在设计连接管理的时候想了一下,觉得在用户请求连接的时候不需要向连接管理请求添加新连接。

因为用户在连接但是没有登录之前,唯一能做的操作就是注册或者登录,并不能接收消息,因此不需要让其它模块拿到没有登录的连接的socket。

所以连接管理模块只需要维护已登录用户的socket。

然后,这样连接管理模块只面向处理模块,处理模块要做的就是提供用户的id,然后让连接管理模块返回其socket,再进行进一步处理。


再改,画了模块图之后

我发现目前的设计消息手法三个子模块之间没啥关联。并且消息处理和消息收发连接太紧密了(耦合高,内聚低),还有个问题就是这样设计消息处理在调用连接管理api的时候也会涉及到socket的传输,这样耦合又提高了,假如以后我想换种协议交互的话,消息处理模块也要大改。因此我想要对消息处理隐藏掉关于通信协议的问题,socket就让消息手法模块内部消化就好,然后消息收发模块和消息处理模块之间使用user_id进行交互。模块图遂改成如下的模式。

2.用户发送消息

3.用户登录(特殊的用户发送消息的情况)

可以看到这个过程不是处理模块驱动的消息发送(因为用户登录前连接管理里面还没有用户id和socket对应的记录)。

所以我目前想到并采取的方案就是让处理模块在处理完登录(或者注册)请求后返回user_id和要返回的内容给接收模块。

接收模块添加了连接之后,再驱动消息发送模块返回这个包。

4.服务器主动向指定用户发送消息

这个还没想好,不过目前打算给处理模块开个接口,后面再开一个线程就可以实现服务器自动发消息了。

三、接口定义

1.接收模块

只有一个对局域网客户端开放的tcp端口,接收tcp报文。

不过这里定义一下发给消息处理模块的参数形式和消息处理模块返回的参数形式

Info {
user_id: Option<String>,
package: Option<Package>
}

Package {
data: Vec<u8>
}

2.连接管理模块

①add_conn(user_id:string, conn:socket) 添加一个连接

②get_conn(user_id:string) 获取指定用户的连接

③set_conn(user_id:string, conn:socket) 修改指定用户的连接

④remove_conn(user_id:string) 删除指定用户的连接

3.消息发送模块

①add_package(receiver_id:string, package: Package)

②send_package(conn:socket, package: Package)

四、代码实现

具体代码见github,这里只讲一些开发中引起我注意的地方。

今天刚做好上面的设计,如果是一般的面向对象语言,我觉得我当天应该可以做完这个大模块。可是我选择的是Rust,第一次实操面对并发访问,汗流浃背了,容我再沉淀沉淀。 不过这也是Rust“适合”用于学习的原因之一,永远会强迫你思考平常不会思考甚至是逃避的问题。


3/29号续

还是卡住了。本来是卡在了rCore第四章实现,想着做这个项目提升rust编程水平,结果做到异步编程还是卡住了。今天去补异步编程,结果才意识到自己rust的基础是如此薄弱,之前主要都去关注原理了,实践能力还没跟上。
所以从今天开始准备补一下rust圣经的进阶实战部分。
感叹学习也是一种递归的过程啊,已经和我最开始的目标有点远了,不过这也说明之前目标定的太高了,学完rust基础语法就直接学rCore,想着一边增强实践能力,一边把操作系统深入理解下。结果还是要回到基础开始。不过绕远路也是一种捷径。

💬 评论区

写评论

暂无评论,来发表第一条吧。

© 2026 Corn 的自留地