C/C++套接字和一个非阻塞recv()
C/C++ sockets and a non-blocking 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: %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
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '