文档结构调整
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
# NET Socket FTP 支持改造方案
|
||||
|
||||
## 背景
|
||||
|
||||
在 net_socket API 上移植 FTP Server(lftpd),需要支持 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)
|
||||
- 设 1:PASV 监听者 `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 部分不碰 SPI,UDP 暂无需跨任务调用)。
|
||||
|
||||
## 向后兼容
|
||||
|
||||
- 控制通道 `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()`
|
||||
Reference in New Issue
Block a user