Socket 常见报错排查
以下整理了 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 相关的问题。