客户报告了一个我无法理解的错误。基于 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);
}
即使在连接关闭之后,读取调用是否有可能永远阻塞?
我的包装器中是否有某种我没有注意到的棘手错误可能导致这种情况?我应该在连接时为套接字设置一些标志吗?