Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C++;套接字和非阻塞recv()_C++_C_Sockets - Fatal编程技术网

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

C++ C/C++;套接字和非阻塞recv(),c++,c,sockets,C++,C,Sockets,我遇到了一个问题,调用recv()系统调用无法阻止。目前我有一个客户机-服务器结构设置,我遇到的问题是我向服务器发送了一条消息,而服务器的设置是这样的: while (1) { char buf[1024]; recv(fd, buf, sizeof(buf), flags); processMsg(buf); } 它正确地接收第一条消息,但recv()不会阻止并“接收”垃圾数据,这不是所需的数据。我只想在邮件发送时才对其作出反应。有人能提供建议吗 如果您在windows上,

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

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

它正确地接收第一条消息,但recv()不会阻止并“接收”垃圾数据,这不是所需的数据。我只想在邮件发送时才对其作出反应。有人能提供建议吗

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

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

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

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

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


我无法与windows行为对话。

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

while() {
    char buf[1024];
    int ret = recv(,buf,,)

    if(ret < 0) {
        // handle error
        printf("recv error: %s\n", strerror(errno));
    } else {
        // only use the first ret bytes of buf
        processMsg(buf, ret);
    }
}

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

您最好检查
recv
中的返回代码。当你高兴地看着缓冲区中的一些垃圾时,它可能会尖叫出错误……你还需要考虑接收部分消息或超过一条消息值的字节的可能性。如果发件人发送500字节的消息,则RECV呼叫可能仅检索200字节或检索700字节(如果发件人可以在不等待响应的情况下发送多条消息)。应该在我之前的评论中包含指向的链接。这两个链接都没有意义,除非
recv
返回-1。第二个if语句(sockfg=>sockfd)中有输入错误。还有两种可能性:流结束或部分消息。你的代码没有检查前者。
// 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
}