Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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++;在Unix上_C++_Sockets_Unix_Timeout - Fatal编程技术网

C++ 如何在c++;在Unix上

C++ 如何在c++;在Unix上,c++,sockets,unix,timeout,C++,Sockets,Unix,Timeout,我想将read()与ioctl()一起使用,但希望通过使用超时来控制read应该等待的时间。 你知道怎么做吗 到目前为止,我所知道的是: //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()与ioctl()一起使用,但希望通过使用超时来控制read应该等待的时间。 你知道怎么做吗

到目前为止,我所知道的是:

//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()
)。使用
设置的超时,因此每次接收到新数据时,都可能会重置\u RCVTIMEO
。因此,对于您的示例,它可能会等待10秒
poll()
在指定的超时后返回,告诉您是否有任何数据。一旦出现这种情况,您就可以使用非阻塞
read()

ioctl()
来读取任何内容,但它不会执行您想要的操作。要在读取时使用超时,您需要使用
poll()
或旧的接口
select()
(我会使用
poll()
)。使用
设置的超时,因此每次接收到新数据时,都可能会重置\u RCVTIMEO
。因此,对于您的示例,它可能会等待10秒
poll()
在指定的超时后返回,告诉您是否有任何数据。一旦出现这种情况,您就可以使用非阻塞
read()

读取任何内容,您确定它在读取时阻塞,还是在连接时阻塞()?我不相信SO_RCVTIMEO(和SO_SNDTIMEO)选项会影响connect()行为


一般来说,我喜欢使用非阻塞套接字(fcntl with O_NONBLOCK),然后捕获eWooldBlock errno并对读取集中的套接字和所需的超时执行select()。

您确定它在读取时阻塞,还是可能在连接时阻塞()?我不相信SO_RCVTIMEO(和SO_SNDTIMEO)选项会影响connect()行为


一般来说,我喜欢使用非阻塞套接字(fcntl with O_NONBLOCK),然后捕获eWooldBlock errno,并对读取集中的套接字和所需的超时执行select()。

您可以通过设置警报来中断系统调用来完成所需的操作。您需要在主程序或程序初始化过程的早期进行一些基本设置:

#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
#包括
信号原子报警计数器;
无效报警处理程序(int信号){
报警_计数器++;
}
无效设置\报警\处理程序(){
struct-sigaction-sa;
memset(&sa,0,sizeof(sa));
sa.sa_handler=报警_handler;
sa.flags=0;
if(sigaAction(SIGALRM,&sa,0)<0)
die(“无法建立信号处理器”);
}
//在主菜单中调用设置\报警\处理程序
然后,您可以像这样使用它:

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
报警(10);//设置10秒超时
(len=connect(mysocket和sock_dest,sizeof(struct sockaddr))<0||
(len=read(mysocket,buffer,10));
警报(0);//如果警报尚未发生,则取消警报
如果(len==1&&errno==EINTR)
//在读取任何数据之前超时
else if(len==-1)
//其他错误

通过这种方式,您可以为一系列调用设置超时(如果连接或读取单独或总共花费的时间过长,则会超时),而不必计算每个调用花费的时间,这样,您就知道每次后续呼叫需要等待多长时间。

您可以通过设置警报来中断系统呼叫。您需要在主程序或程序初始化过程的早期进行一些基本设置:

#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
#包括
信号原子报警计数器;
无效报警处理程序(int信号){
报警_计数器++;
}
无效设置\报警\处理程序(){
struct-sigaction-sa;
memset(&sa,0,sizeof(sa));
sa.sa_handler=报警_handler;
sa.flags=0;
if(sigaAction(SIGALRM,&sa,0)<0)
die(“无法建立信号处理器”);
}
//在主菜单中调用设置\报警\处理程序
然后,您可以像这样使用它:

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
报警(10);//设置10秒超时
(len=connect(mysocket和sock_dest,sizeof(struct sockaddr))<0||
(len=read(mysocket,buffer,10));
警报(0);//如果警报尚未发生,则取消警报
如果(len==1&&errno==EINTR)
//在读取任何数据之前超时
else if(len==-1)
//其他错误

通过这种方式,您可以为一系列调用设置超时(如果连接或读取单独或总共花费的时间过长,则会超时),而不必计算每个调用花费的时间,这样您就可以知道每次后续调用的等待时间。

您可以尝试使用设置
O_NONBLOCK
,然后使用来确定套接字何时可以读取(选择允许您指定超时)。同意。顺便说一句,如果您关心读取
需要多长时间,您可能也应该关心连接
需要多长时间(如果超时,可能需要一段时间)。您可以在调用
connect
之前使套接字非阻塞,并通过
select
poll
进行处理。您可以尝试使用设置
O_NONBLOCK
,然后使用确定套接字何时可以读取(选择允许您指定超时)。同意。顺便说一句,如果您关心读取
需要多长时间,您可能也应该关心连接
需要多长时间(如果超时,可能需要一段时间)。在调用
connect
之前,您可以使套接字非阻塞,并通过
select
poll
处理。我正在使用ioctl检查可以读取多少字节,如果还没有准备好,请再次循环,但读取是阻塞调用,请使用timeout继续。其目的是替换SELECT调用。那么,将
SO_RCTTIMEO
设置为
timeout/size
(其中
timeout
以秒为单位,
size
以字节为单位)的效果应该与此类似。但是,这个标志似乎不太便于携带,我仍然会使用
poll()
(或者
select()
,如果
poll()
不知何故不可用)。为什么要删除这些呼叫?他们处理得很好