Socket 常见报错排查

[English]

以下整理了 ESP-IDF 中 Socket 常见的报错日志,对应原因和可能的解决办法。

示例:transport_base: poll_read select error 113, errno = Software caused connection abort, fd = 56

错误信息解析:

  • poll_read select error 113

  • errno = 113 (Software caused connection abort)

  • fd = 56

可能原因:

  • 113 一般是 TCP keepalive 心跳超时,重传超时导致的链路断开异常。

解决方案:

  • 检查服务器端是否有异常日志。

  • 确保网络连接稳定。

  • 在应用层实现心跳机制,避免长时间无数据通信导致连接断开。

备注

在分析 TCP 流异常问题时,可以使用 调试补丁脚本 来打印 TCP 序列号等信息,帮助定位问题。

使用方法:在终端中进入 ESP-IDF 主目录,执行命令 python <path to at_net_debug.py> 应用此补丁。应用补丁后,后续 ESP 日志中将会包含 TCP 序列号(seq)和确认号(ack)等调试信息。

常见 errno 及其分析

Errno 定义

对应的值

对应的 ERR

对应解释

产生的原因

定位措施

ENOMEM

12

ERR_MEM

Out of memory error

分配内存失败或者 mailbox 满了,msg 发送失败

打印剩余内存和最小内存,查看是否存在内存不足

ENOBUFS

105

ERR_BUF

Buffer error

1. 空间大小不够,包头长度超过了分配的长度 2. socket 分配 netconn 失败 3. option len 过长

加 log 定位

EWOULDBLOCK

11

ERR_TIMEOUT / ERR_WOULDBLOCK

Timeout / Operation would block

1. Timeout – 接收超时(设置了 SO_RCVTIMEO) 2. Operation would block – non-blocking 下收发调用过快 3. Operation would block – 发送超时(设置了 SO_SNDTIMEO)

在 ERR_TIMEOUT 处添加打印;nonblocking 后连接/发送/接收都是立刻返回的,应用层要处理好

EHOSTUNREACH

118

ERR_RTE

Routing problem

找不到出去的路由(netif)

加 log 定位,看目的 IP 是否有满足的路由接口

EINPROGRESS

119

ERR_INPROGRESS

Operation in progress

操作正在进行中,非阻塞模式下 connect 会遇到,DNS 查询时也会遇到

正常的 errno

EINVAL

22

ERR_VAL

Illegal value

参数错误(option 设置的参数,select/poll 传入的 fd)

检查调用函数的参数是否有问题

EADDRINUSE

112

ERR_USE

Address in use

绑定时地址或端口已被绑定

查看绑定的地址或端口是否被绑定,可用 SO_REUSEADDR 解决

EALREADY

120

ERR_ALREADY

Already connecting

套接字已在连接或已处于 listen 状态,应用层又调用 connect 或 listen

查看代码逻辑

EISCONN

127

ERR_ISCONN

Conn already established

套接字已处于 Connected

查看代码逻辑

ENOTCONN

128

ERR_CONN / ERR_CLSD

Not connected / Connection closed

socket 处于未连接状态或对端断开连接 FIN

一般是对端断开了连接,我们还在使用该 socket 发送数据,抓包确定

ECONNABORTED

113

ERR_ABRT

Connection aborted

链接由于错误状态或对方原因断开,或 TCP timer 超时,移除链接(一般是本端断开链接)

加 log 定位

ECONNRESET

104

ERR_RST

Connection reset

收到对端发送的 RST

抓包确定

EIO

5

ERR_ARG

Illegal argument

输入参数错误

查看出现这个问题的上一个操作,加 log 定位

EBADF

9

Bad file number

socket 已经无效

加 log 定位

ENOPROTOOPT

109

Protocol not available

协议不支持,一般是 getsockopt/setsockopt 的 option 不支持

定位 option 是否支持

1

ERR_IF

Low-level netif error

netif 接口错误

一般是底层接口是 NULL,比如加入组播组传入的接口 index,底层查询是 NULL。

总结

  • 通过 errno 代码,可以快速定位 socket 问题的根因。

  • 结合日志分析,可以优化错误处理,提升系统稳定性。

  • 使用 getsockopt() 读取 SO_ERROR 获取更多错误信息。

希望这些信息能帮助排查 ESP-IDF Socket 相关的问题。