修改网络的初始化,异步支持问题

This commit is contained in:
2026-07-21 01:22:09 +08:00
parent fbe0726991
commit f50b9c9e66
7 changed files with 337 additions and 138 deletions

View File

@@ -0,0 +1,80 @@
# NET Socket FTP 支持改造方案
## 背景
在 net_socket API 上移植 FTP Serverlftpd需要支持 PASV 模式数据通道。现有 API 仅支持"一个监听 Socket 独占全部数据 Socket"的单 TCP Server 模型,改造后需支持**多监听者 + 动态 Socket 分配**。
## Socket 需求量
| 用途 | Socket | 说明 |
|------|--------|------|
| 控制通道监听(端口 21 | Socket 0 | 多连接 TCP Server |
| 控制通道数据 | Socket 1 | backlog=1只接受 1 个 FTP 客户端 |
| PASV 数据监听 + 传输 | Socket 2 | 动态分配,用后释放 |
| 空闲 | Socket 3~7 | 备胎 |
## 改造项7 项)
### A. `net_sock_t` 新增 `standalone_accept` 标志
- 位置:`net_types.h:net_sock_t`
- 用途:区分多连接数据 Socket 和独立监听者(如 PASV
- 设 1PASV 监听者 `handle_connect_event` → 原地转为 `ESTABLISHED`
- 设 1`handle_disconnect_event` → 释放(`CLOSED`),不恢复 `TCP_ACCEPT`
### B. `net_listen()` 按 backlog 分配 + 登记 data_socks[]
- 循环从 `NET_TCP_SERVER_DATA_SOCK_START``backlog`
- 分配的数据 Socket 登记到 `p_sock->data_socks[]`,设 `data_sock_count`
- `backlog == 0` 时:不分配数据 Socket`standalone_accept=1`
### C. `net_bind()` 支持 port=0 自动分配
- `sin_port == 0` 时从 49152~65535 分配
- 静态变量 `s_dynamic_port` 递增
### D. `handle_connect_event()` 支持独立监听
- `LISTENING + standalone_accept`:拷贝远程 IP/Port状态转 `ESTABLISHED`
- `LISTENING + !standalone_accept`:保持 LISTENING现有行为
### E. `handle_disconnect_event()` 支持独立释放
- `ESTABLISHED + standalone_accept`:设 `state = CLOSED, in_use = 0`(释放)
- `ESTABLISHED + !standalone_accept`:恢复 `TCP_ACCEPT`(现有行为)
- 释放时不清零整个控制块(正在 `net_recv` 中的任务仍需读取 state
### F. `net_accept()` 支持单连接 + 修复多连接
- 先查 `data_socks[]`(修复现行 bug
- 再查 `standalone_accept` 监听者是否 `ESTABLISHED` → 返回自身
### G. 新增 `net_getsockname()`
- 返回 `local_port` + 本机 IP
- 本机 IP 在 `net_init()` 时缓存(`s_local_ip`),避免 SPI 竞态
## 消息队列序列化
### 问题
`net_listen()``net_accept()` 直接调用 CH395F SPI从非 netTask如 FTP 任务)调用会与 `net_poll()` 冲突。
### 方案
新增消息类型通过现有消息队列串行化:
| 消息类型 | 用途 | 状态 |
|---------|------|------|
| `NET_MSG_LISTEN` | `net_listen()` 委托 netTask 执行 | 本次实现 |
| `NET_MSG_ACCEPT` | `net_accept()` 委托 netTask 执行 | 本次实现 |
`net_bind()` 暂不消息化TCP 部分不碰 SPIUDP 暂无需跨任务调用)。
## 向后兼容
- 控制通道 `net_listen(sockfd=0, backlog=7)` 行为不变(仍配满 Socket 1~7
- `backlog < 7` 时才释放多余 Socket
- `NET_MSG_LISTEN`/`NET_MSG_ACCEPT` 仅新增,不影响现有 `NET_MSG_SEND/RECV/CLOSE/CONNECT`
- `net_sock_t` 新增字段 `standalone_accept` 默认 0不影响现有使用
## 实施顺序
1. 消息队列加 `NET_MSG_LISTEN``NET_MSG_ACCEPT`
2. `net_listen()` 消息化 + 按 backlog 分配 + data_socks 登记
3. `net_accept()` 消息化 + 单连接支持
4. `net_bind()` port=0 支持
5. `net_types.h` standalone_accept 字段
6. `handle_connect_event()` / `handle_disconnect_event()` 独立监听逻辑
7. `net_getsockname()`