如何在Unix上的c++套接字上使用带有read()的超时
how to use timeouts with read() on a socket in c++ on Unix
我想将read()与ioctl()一起使用,但想通过使用超时来控制读取应该等待的时间。你知道怎么做吗?
到目前为止,我所知道的是:
//CLIENT.cpp
struct timeval tv={1,0};
setsockopt( mysocket, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(tv));
connect(mysocket, &sock_dest, sizeof(struct sockaddr));
len = read(mysocket, buffer, 10);
我尝试在服务器上使用5秒的延迟,但它没有超时。。。
ioctl()
不会执行您想要的操作。要在读取时使用超时,您需要使用poll()
或较旧的接口select()
(我会使用poll()
)。利用SO_RCVTIMEO
设置的超时可以在每次接收到新数据时被重置。因此,对于您的示例,它可能会等待长达10秒。poll()
在指定的超时后返回,告诉您是否有任何数据。一旦出现这种情况,您就可以使用非阻塞read()
读取任何内容。
您可以通过设置警报来中断系统调用来执行您想要的操作。您需要在主程序或程序初始化过程的早期进行一些基本设置:
#include <signal.h>
sig_atomic_t alarm_counter;
void alarm_handler(int signal) {
alarm_counter++;
}
void setup_alarm_handler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = alarm_handler;
sa.flags = 0;
if (sigaction(SIGALRM, &sa, 0) < 0)
die("Can't establish signal handler");
}
// call setup_alarm_handler in main
然后,你可以像这样使用它:
alarm(10); // set a 10 second timeout
(len = connect(mysocket, &sock_dest, sizeof(struct sockaddr))) < 0 ||
(len = read(mysocket, buffer, 10));
alarm(0); // cancel alarm if it hasn't happened yet
if (len == -1 && errno == EINTR)
// timed out before any data read
else if (len == -1)
// other error
通过这种方式,您可以为一系列调用设置超时(如果连接或读取单独或总共花费的时间太长,则会超时),而不必计算每个调用花费的时间,这样您就知道等待每个后续调用需要多长时间。
您确定它在读取时被阻塞,还是可能在connect()上被阻塞?我不认为SO_RCVTIMEO(和SO_SNDTIMEO)选项会影响connect()行为。
通常,我喜欢使用非阻塞套接字(fcntl with O_NONBLOCK),然后捕获EWOULDBLOCK错误号,并使用读取集中的套接字和所需的超时值执行select()。
相关文章:
- C++减少modbus_connect超时
- 没有超时的C++条件变量
- 使用 ImageIO.read() 生成的图像是否仍然使用传递给它的相同内存?
- 如何在C++(VS2010)中设置超时读取USB端口?
- C++卷曲柱在curl_easy_perform超时
- std::ifstream::read 不会读取所有 512 字节,并设置 EOF 和失败位
- 如何在Qt 4.8中阻止/忽略/丢弃早于特定超时的用户输入事件
- 如何改进我的代码,使其不会因超时而终止?(黑客排名挑战)
- write() 和 read() 中几乎没有混淆
- C++:函数外部的超时功能
- 使用boost::multiprecision cpp_int左移时出现超时错误
- C++ TCP 套接字通信 - 连接按预期工作,几秒钟后失败,没有收到新数据,read() 和 recv() 块
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 对同一文件使用 .read 的次数是否有限制?
- QTimer 超时不会在单元测试中触发
- 使用单体计时器的pthread_cond_timedwait有时会比预期晚超时
- Win32 API - HWND "{unused = ???} Unable to read memory"错误
- 超时后,线程睡眠不会继续执行
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- 如何在Unix上的c++套接字上使用带有read()的超时