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

我遇到一个调用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: %s\n", 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