c - tcp 套接字读取调用如何永远不会返回

标签 c sockets tcp client-server buffer

一位客户报告了一个我无法理解的错误。基于 TCP 的客户端连接到它从中接收数据的服务器,很少发送任何东西。通常一切正常,但在极少数情况下会发生这样的情况:

  • 服务器发送一些数据
  • 客户端接收数据
  • 客户端正在处理数据
  • ...同时服务器发送更多数据
  • 客户完​​成处理
  • 客户端尝试从套接字读取数据
  • 客户端在处理后永远卡在第一个 read() 语句上
  • 服务器关闭连接
  • 客户端仍然挂起

这是建立 tcp 连接的方式(去除所有日志、返回检查等)

ret = inet_pton(AF_INET, conn->address, &addr.sin_addr);
addr.sin_port        = htons(conn->port); /* Server port */
addr.sin_family      = AF_INET;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (struct sockaddr *) &addr, sizeof(addr));

这是读取包装器:

int32_t _readn ( int fd, uint8_t *vptr, int32_t n )
{
  int32_t  nleft;
  int32_t  nread;
  uint8_t*     ptr;

  ptr = vptr;
  nleft = n;
  while (nleft > 0) {
    if ((nread = read (fd, ptr, nleft)) < 0) {
      if (errno == EINTR) {
        nread = 0;
      } else {
        return E_NETWORK_ERROR;
      }
    } else if ( nread == 0 ) {
      break;
    }
    nleft -= nread;
    ptr   += nread;
  }
  return  (n-nleft);
}

读取调用是否可能永远阻塞,即使在连接关闭后也是如此?

我的包装器中是否存在某种我没有注意到的棘手错误可能会导致这种情况?我应该在连接时为套接字设置一些标志吗?

最佳答案

问题的根源是如果没有数据读取就会阻塞。例如。如果写入的字节少于预期的 n 个字节。这称为阻塞读取。

如 Jite 所说,要发现是否有数据,请使用 select

最后,您的防火墙可能会断开实时连接。一些防火墙配置为切断打开时间超过给定时间的连接,例如30分钟。然而,这可能不是您所拥有的。

关于c - tcp 套接字读取调用如何永远不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15112717/

相关文章:

c++ - SWIG 接口(interface)文件问题

c- valgrind(无效的 free()/delete/delete[]/realloc())套接字

Java程序通过socket接口(interface)与邮件服务器建立TCP连接并发送邮件

tcp - Erlang TCP 服务器处理

c - 是否可以根据/proc/self/maps中的信息来执行munmap?

c - 为什么 printf 打印的内容大于数组的大小?

c - 链接描述文件部分未出现在 ELF 上

Python,套接字。或没有套接字(调试帮助)

linux - IPC Unix 域套接字 bash

JAVA:TCP readline() 终止,二进制零