HarmonyOS 鸿蒙Next中tcp连接建立以后,用read读socket读不到,错误码是11 (11: Resource temporarily unavailable)

HarmonyOS 鸿蒙Next中tcp连接建立以后,用read读socket读不到,错误码是11 (11: Resource temporarily unavailable) 【问题描述】:我用ndk编译的第三方C库,用ts调用了这个连接功能
现在有个问题,tcp连接建立以后,用read读socket读不到,错误码是11 (11: Resource temporarily unavailable)

【问题现象】:报错(11: Resource temporarily unavailable)

【版本信息】:不涉及

【复现代码】:不涉及

【尝试解决方案】:不涉及

5 回复

开发者您好,麻烦请提供一下以下信息:
1.问题现象(如:报错日志(获取方式:xxx)、异常截图、问题背景);
2.复现代码(如最小复现demo);
3.版本信息(如:开发工具、手机系统版本信息);

更多关于HarmonyOS 鸿蒙Next中tcp连接建立以后,用read读socket读不到,错误码是11 (11: Resource temporarily unavailable)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你可以丢出代码

你这个大概是非阻塞模式下的 I/O 操作导致的

在鸿蒙Next中,TCP连接建立后read返回错误码11(EAGAIN/EWOULDBLOCK),表示socket被设置为非阻塞模式且当前无数据可读。这通常是因为socket配置了O_NONBLOCK标志。检查socket创建或设置过程,确认是否调用了fcntl或ioctl设置了非阻塞属性。

错误码11(EAGAIN/EWOULDBLOCK)表示socket当前处于非阻塞模式,且没有立即可读的数据。在HarmonyOS Next中,这通常是由于socket被设置为非阻塞模式,而read操作无法立即完成导致的。

主要原因及解决方案:

  1. 检查socket是否被设置为非阻塞模式

    • 如果通过fcntlioctl设置了O_NONBLOCK标志,read在无数据时会立即返回EAGAIN。
    • 处理方式:改用阻塞模式(默认),或使用select/poll/epoll等待数据就绪后再read。
  2. 确认对端是否已发送数据

    • 使用selectpollepoll监控socket的可读事件,确保数据到达后再调用read。
    • 示例(使用select):
      fd_set read_fds;
      FD_ZERO(&read_fds);
      FD_SET(sockfd, &read_fds);
      struct timeval timeout = {5, 0}; // 5秒超时
      int ret = select(sockfd + 1, &read_fds, NULL, NULL, &timeout);
      if (ret > 0 && FD_ISSET(sockfd, &read_fds)) {
          // 此时调用read可避免EAGAIN
          read(sockfd, buffer, sizeof(buffer));
      }
      
  3. 检查socket连接状态

    • 确保连接已成功建立(对端未关闭),可通过getsockopt检查错误码或心跳机制验证连通性。
  4. 调整接收缓冲区大小

    • 若对端发送的数据大于socket接收缓冲区,可能触发EAGAIN。可通过setsockopt调整SO_RCVBUF:
      int buf_size = 64 * 1024; // 64KB
      setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(buf_size));
      
  5. 第三方库的兼容性

    • 确认NDK编译的C库是否完全兼容HarmonyOS Next的POSIX接口,特别是socket相关系统调用。

建议排查步骤:

  • 使用fcntl(sockfd, F_GETFL, 0)检查socket的文件状态标志,确认是否包含O_NONBLOCK。
  • 添加日志输出,记录read调用前后的errno值及socket状态。
  • 若对端为慢速发送,需实现异步等待机制,避免轮询消耗资源。

此错误属于正常异步处理场景,需根据业务逻辑选择阻塞等待或事件驱动方式读取数据。

回到顶部