我遇到一个调用recv()系统调用没有阻塞的问题.我目前有一个客户端 - 服务器结构设置,我遇到的问题是我向服务器发送一条消息,而服务器设置为以下是这样的:
while (1) {
char buf[1024];
recv(fd, buf, sizeof(buf), flags);
processMsg(buf);
}
Run Code Online (Sandbox Code Playgroud)
它正确接收第一条消息,但recv()不会阻止和"接收"不是所需的垃圾数据.我只想在发送消息时才对消息做出反应.任何人都可以建议吗?
Duc*_*uck 15
recv()不一定会阻塞,直到满足完整请求,但可以返回部分请求.返回代码将通知您实际接收的字节数可能少于您的请求.即使您指定了MSG_WAITALL标志,它也可以因信号等而返回较少.
在posix系统上,在阻塞模式下,recv将仅阻塞直到某些数据被读取.然后它将返回可能少于请求的数据,直到请求的数量.在非阻塞模式下,如果要读取零字节数据,recv将立即返回,并返回-1,将errno设置为EAGAIN或EWOULDBLOCK.
结果是通常你会在一个循环中调用recv,直到你得到你想要的数量,同时还检查返回代码0(另一侧断开)或-1(一些错误).
我不能说窗户的行为.
Ada*_*eld 13
有两种可能性:发生错误,或者套接字设置为非阻塞模式.要查看是否发生错误,请检查返回值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);
}
}
Run Code Online (Sandbox Code Playgroud)
为了把插座成非阻塞模式,或者查询如果套接字是非阻塞模式,采用fcntl(2)与O_NONBLOCK标志:
// 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
}
Run Code Online (Sandbox Code Playgroud)
请注意,除非您明确更改阻止行为,否则默认情况下套接字应该是阻塞的,因此很可能发生错误.