feat(NET): N34 阶段 1.5 recv 语义主流化——无限默认+具名非阻塞+模式属性
核心语义(实施方案 §3.5): - net_recv 默认无限阻塞:删除 NET_RECV_TIMEOUT_MS(30s 隐藏默认预算), 超时归调用方策略;唤醒源=数据/EOF/close/网络重建(CONNRESET), 会话死亡由对账① ~400ms 判死兜底,无"对端消失永久挂死"窗口 - 新增 net_recv_nb(NET_MSG_DONTWAIT 路径转正具名)与 net_setblocking(fd,on)(阻塞模式挂控制块属性,对齐 O_NONBLOCK/ Python setblocking;直写单字节,net_set_event_cb 先例) - net_types.h net_sock_t 新增 blocking 属性;net_socket() 默认置 1 (close memset 清零后显式重置,同 released_abnormal 纪律) - 原 1s 强制了结看门狗降级为 60s tripwire:只 [ERR] 留痕一次, 绝不伪造 TIMEDOUT 返回值(旧实现掩盖完成路径缺陷) - net_recvfrom 删 30s 自旋超时、同判据对齐(零生产调用者,注释警示) - 文档契约:IWDG required_mask 内任务禁止无限阻塞 recv(BSD 指南 §3.5/§10.1 + net_socket.h 注释) 调用点审计(§3.5.5):零生产调用点采用无限默认——iec104_serv/ ui_net_sink 转 net_recv_nb(受监控任务逐位等价);lftpd/time_sync 已是显式预算 net_recv_to 不动;32 轮盲收兜底未动(阶段 3 E6 门禁) 模拟器双端镜像 net_recv_nb/net_recv_to/net_setblocking(包装层 Sleep(1) 轮询模拟阻塞);差距清单 N-3/N-6 登记义务已履行 门禁与台架: - @build 0/0:Code 209580→209780(+200B) ZI +32B;RAM 受管区官方 脚本同步;ci_local L0 32/32 + L0.5 951/951 - 台架全回归:relisten :7003 50/50、iec104 18/18、对时正常、 ftp_regression 11/11、Trap23 RST 5/5+FIN 5/5、ftp_integrity 20/20 字节一致、n30 0/10、@test PASS - 模拟器 build_sim OK + check_remo_sink 黄金参考 0/25600 位差 队友 p15-recv-semantics 实施,Lead 全量审阅 + 独立复跑门禁与回归
This commit is contained in:
@@ -48,7 +48,8 @@ typedef struct {
|
||||
void *buf; /* 数据缓冲区(send/recv) */
|
||||
int len; /* 数据长度/缓冲区大小 */
|
||||
int flags; /* 接收标志 */
|
||||
uint32_t timeout_ms; /* 接收超时(入队方向;0 = 用默认 NET_RECV_TIMEOUT_MS) */
|
||||
uint32_t timeout_ms; /* 接收超时(入队方向;0 = 无限等待,无默认预算——
|
||||
* N34 阶段 1.5 删除 NET_RECV_TIMEOUT_MS 30s 默认) */
|
||||
TaskHandle_t caller; /* 调用方任务句柄 */
|
||||
int result; /* 操作结果 */
|
||||
/* 连接参数 */
|
||||
@@ -230,19 +231,55 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen);
|
||||
int net_send(int sockfd, const void *buf, int len, int flags);
|
||||
|
||||
/*
|
||||
* 函数功能:接收数据(TCP)
|
||||
* 函数功能:接收数据(TCP,**默认无限阻塞**——N34 阶段 1.5 语义主流化)
|
||||
* 入口参数:sockfd - socket 描述符
|
||||
* buf - 接收缓冲区
|
||||
* len - 缓冲区大小
|
||||
* flags - 通常为 0,可设置 NET_MSG_DONTWAIT 非阻塞
|
||||
* flags - 通常为 0;NET_MSG_DONTWAIT 单次强制非阻塞
|
||||
* 返回值:实际接收字节数,0=对端关闭,-1=错误
|
||||
* 限定条件:TCP 连接已建立
|
||||
* 函数说明:在阻塞模式下,如果没有数据,函数会等待;
|
||||
* 在非阻塞模式下,如果没有数据,返回 -1 并设置
|
||||
* net_errno 为 NET_ERR_WOULDBLOCK
|
||||
* 函数说明:1. 无数据时**无限等待**(无默认超时预算,对齐 POSIX/Python:模式归
|
||||
* 使用者、超时归调用方);唤醒源 = 数据 / EOF / close / 网络重建
|
||||
* (NET_ERR_CONNRESET)——会话死亡由对账①在 ~400ms 内判死兜底,
|
||||
* 不存在"对端消失后永久挂死"的窗口
|
||||
* 2. 模式属性:net_setblocking(fd, 0) 后本接口无数据立即返回
|
||||
* NET_ERR_WOULDBLOCK;NET_MSG_DONTWAIT 仅单次覆盖该属性
|
||||
* 3. ⚠ 文档契约(嵌入式特有):IWDG required_mask 内任务**禁止无限
|
||||
* 阻塞 recv**——必须 net_select 超时或 net_recv_to 显式预算,
|
||||
* 否则"对端连上不发数据"= IWDG 复位(超时归使用者对受监控任务是义务)
|
||||
* 4. 超时首选 net_select(r,w,e,timeout_ms);net_recv_to 为显式预算便捷入口
|
||||
*/
|
||||
int net_recv(int sockfd, void *buf, int len, int flags);
|
||||
|
||||
/*
|
||||
* 函数功能:接收数据(非阻塞具名入口,原 NET_MSG_DONTWAIT 路径转正——N34 阶段 1.5)
|
||||
* 入口参数:sockfd - socket 描述符
|
||||
* buf - 接收缓冲区
|
||||
* len - 缓冲区大小
|
||||
* 返回值:实际接收字节数;0 = 对端关闭(net 层已自动重监听);
|
||||
* -1 = 错误(无数据 = NET_ERR_WOULDBLOCK,其余 errno 可查)
|
||||
* 限定条件:非 netTask 上下文(netTask 内用 net_recv_sock + DONTWAIT)
|
||||
* 函数说明:等价 net_recv(sockfd, buf, len, NET_MSG_DONTWAIT);
|
||||
* 不改变 socket 的 blocking 属性(模式用 net_setblocking 设置)
|
||||
*/
|
||||
int net_recv_nb(int sockfd, void *buf, int len);
|
||||
|
||||
/*
|
||||
* 函数功能:设置 Socket 阻塞/非阻塞**模式属性**(对齐 BSD O_NONBLOCK / Python
|
||||
* setblocking——N34 阶段 1.5,模式挂 socket 控制块属性)
|
||||
* 入口参数:sockfd - socket 描述符
|
||||
* on - 1 = 阻塞(net_socket 默认);0 = 非阻塞
|
||||
* 返回值:0 成功;-1 失败(描述符无效/未占用)
|
||||
* 限定条件:socket 已创建
|
||||
* 函数说明:1. 属性对 net_recv / net_recv_sock 生效:非阻塞模式下无数据立即
|
||||
* 返回 NET_ERR_WOULDBLOCK(EOF 判定语义不变:CLOSED/session_dead
|
||||
* 无数据仍返回 0 并触发自动重监听)
|
||||
* 2. 直写控制块单字节(先例 net_set_event_cb),任意上下文可调;
|
||||
* 最坏一次在途 recv 用旧模式,无撕裂风险
|
||||
* 3. 与超时预算正交:模式是粘滞属性,单次预算用 net_recv_to/net_select
|
||||
*/
|
||||
int net_setblocking(int sockfd, int on);
|
||||
|
||||
/*
|
||||
* 函数功能:接收数据(**带调用方指定超时**的阻塞版,用于分片有界读)
|
||||
* 入口参数:sockfd - Socket 描述符
|
||||
@@ -250,10 +287,14 @@ int net_recv(int sockfd, void *buf, int len, int flags);
|
||||
* timeout_ms - 单次调用在 netTask 内的最长等待(毫秒,>0)
|
||||
* 返回值:>0 实际字节数;0 = 对端关闭(EOF);-1 = 真错误(errno 可查);**-2 = 超时无数据**
|
||||
* 限定条件:非 netTask 上下文;Socket 已连接
|
||||
* 函数说明:为"不能长时间占用 netTask"的调用方(如 lftpd 控制行/数据读)提供
|
||||
* **分片**阻塞:每次调用最多占用 netTask timeout_ms,返回 -2 表示这段
|
||||
* 时间内无数据,调用方自行累计总预算并决定是否继续(E-02 头阻塞修复)。
|
||||
* 超时用独立返回码而非 errno → 无跨任务 errno 竞态。
|
||||
* 函数说明:1. **显式预算**便捷入口(等价 Python settimeout,N34 阶段 1.5 起
|
||||
* 不再有隐藏默认值):net_recv 的无限阻塞 + 本接口的显式预算构成
|
||||
* 超时语义的全部来源;超时首选仍是 net_select
|
||||
* 2. E-02 修复配套:lftpd 等"等对端下一行/下一块数据"的调用方
|
||||
* 若无限阻塞 recv,会把 netTask(全部 socket 操作的唯一执行者)长期占住
|
||||
* 3. 用本接口把等待切成 ≤timeout_ms 的片,调用方自行累计总预算:总超时语义不变、单次占用有界
|
||||
* 4. 超时用独立返回码 -2(而非靠 errno 区分)→ 无跨任务 errno 竞态
|
||||
* 5. ⚠ IWDG required_mask 内任务必须走本接口或 net_select(见 net_recv 契约)
|
||||
*/
|
||||
int net_recv_to(int sockfd, void *buf, int len, uint32_t timeout_ms);
|
||||
|
||||
@@ -277,12 +318,16 @@ int net_sendto(int sockfd, const void *buf, int len, int flags,
|
||||
* 入口参数:sockfd - socket 描述符
|
||||
* buf - 接收缓冲区
|
||||
* len - 缓冲区大小
|
||||
* flags - 通常为 0
|
||||
* flags - 通常为 0;NET_MSG_DONTWAIT 单次强制非阻塞
|
||||
* src_addr - 输出:发送方地址
|
||||
* addrlen - 输入输出:地址长度
|
||||
* 返回值:实际接收字节数,失败返回 -1
|
||||
* 限定条件:socket 已创建,指针非空
|
||||
* 函数说明:读取 CH395F 接收缓冲区,获取对端地址
|
||||
* 函数说明:1. 读取 CH395F 接收缓冲区,获取对端地址
|
||||
* 2. 阻塞语义与 net_recv 同(N34 阶段 1.5):blocking 属性下无数据
|
||||
* 无限等待,DONTWAIT / 非阻塞属性立即 NET_ERR_WOULDBLOCK;
|
||||
* 本接口为轮询自旋实现(历史遗留,UDP 专用),受 IWDG 监控的
|
||||
* 任务同样禁止对其无限等待
|
||||
*/
|
||||
int net_recvfrom(int sockfd, void *buf, int len, int flags,
|
||||
struct net_sockaddr *src_addr, int *addrlen);
|
||||
|
||||
Reference in New Issue
Block a user