Files
STM32F4-Base/docs/NET_Socket_FTP_Support_Plan.md

3.4 KiB
Raw Blame History

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
  • 设 1handle_disconnect_event → 释放(CLOSED),不恢复 TCP_ACCEPT

B. net_listen() 按 backlog 分配 + 登记 data_socks[]

  • 循环从 NET_TCP_SERVER_DATA_SOCK_STARTbacklog
  • 分配的数据 Socket 登记到 p_sock->data_socks[],设 data_sock_count
  • backlog == 0 时:不分配数据 Socketstandalone_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_LISTENNET_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()