C/C++套接字和一个非阻塞recv()

C/C++ sockets and a non-blocking recv()

本文关键字:一个 recv C++ 套接字      更新时间:2023-10-16

我遇到了一个问题,调用recv()系统调用不被阻止。我现在有一个客户端-服务器结构设置,我遇到的问题是我向服务器发送一条消息,而服务器的设置是这样的:

while (1) {
   char buf[1024];
   recv(fd, buf, sizeof(buf), flags);
   processMsg(buf);
}

它正确地接收到第一条消息,但recv()不会阻塞并"接收"垃圾数据,这不是所需的。我只想在信息发送时对其做出反应。有人能提出建议吗?

recv()在完成完整请求之前不一定会阻塞,但可以返回部分请求。返回代码将通知您实际收到的字节数,可能少于您请求的字节数。即使您指定了MSG_WAITALL标志,由于信号等原因,它也会返回较少的信息。

在posix系统上,在阻塞模式下,recv只会阻塞,直到出现要读取的数据为止。然后,它将返回该数据,该数据可能少于请求的数据,最高可达请求的数量。在非阻塞模式下,如果要读取的数据为零字节,recv将立即返回,并返回-1,将errno设置为EAGAIN或EWOULDBLOCK。

结果是,通常情况下,您会循环调用recv,直到获得所需金额,同时检查返回代码0(另一侧已断开连接)或-1(某些错误)。

我不能谈论窗户的行为。

有两种可能性:要么发生错误,要么套接字设置为非阻塞模式。要查看是否发生错误,请检查recv:的返回值

while() {
    char buf[1024];
    int ret = recv(,buf,,)
    if(ret < 0) {
        // handle error
        printf("recv error: %sn", strerror(errno));
    } else {
        // only use the first ret bytes of buf
        processMsg(buf, ret);
    }
}

要将套接字置于非阻塞模式,或查询套接字是否处于非阻塞模式中,请使用带有O_NONBLOCK标志的fcntl(2)

// Test if the socket is in non-blocking mode:
if(fcntl(sockfd, F_GETFL) & O_NONBLOCK) {
    // socket is non-blocking
}
// Put the socket in non-blocking mode:
if(fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK) < 0) {
    // handle error
}

请注意,除非显式地更改阻塞行为,否则套接字在默认情况下应该是阻塞的,因此很可能会发生错误。

如果您在windows上,请运行wsagetlasterror()函数并查看返回值。

http://msdn.microsoft.com/en-us/library/ms741580%28v=vs.85%29.aspx

如果您使用的是posix兼容系统,请查看errno

http://pubs.opengroup.org/onlinepubs/009695399/functions/errno.html