C 设置接收函数的套接字超时

C 设置接收函数的套接字超时,c,tcp,ipc,wait,C,Tcp,Ipc,Wait,我有一个客户机-服务器连接,客户机正在向服务器发送数据 while (1) { bzero(buffer, 256); sleep(1); n = read(sock, buffer); if(n < 0) error("ERROR reading from socket"); c = message[0]; //do something }//close while loop while(1){ b0(缓冲器,256); 睡眠(1

我有一个客户机-服务器连接,客户机正在向服务器发送数据

while (1) {

    bzero(buffer, 256);
    sleep(1);

    n = read(sock, buffer);
    if(n < 0) error("ERROR reading from socket");
    c = message[0];

    //do something

}//close while loop
while(1){
b0(缓冲器,256);
睡眠(1);
n=读取(sock、缓冲器);
如果(n<0)错误(“从套接字读取错误”);
c=消息[0];
//做点什么
}//闭环
问题是,我只想等待读取发生几秒钟——在我的代码中,如果客户机不发送任何内容,它就会在等待服务器读取内容时陷入困境


我怎么能只等几秒钟就开始读取呢?

您可以使用select()api来实现此目的。在这个api中,你可以用秒和微秒来表示select api中的时间。

基本上,
read
调用尝试读取时间,因此如果你不想在它上面获得堆栈,你必须将
sock
变量声明为非阻塞变量,或者使用带超时的
select
函数(
manselect
)。在第一种情况下,您不能等待几秒钟,但您可以尝试读取
k
次,然后进行检查。以下是非阻塞套接字的示例:

/*
 * Non-blocking socket solution
 * just put the read in a for-loop
 * if you want to read k times
 */


#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

int r1;
/*Setting the socket as non-blocking*/
int flags = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
errno = 0; /*If the read fails it sets errno*/
if((r1=read(sock,buf_in,N))== -1) { /*If the read returns an error*/
    if(errno != EAGAIN && errno != EWOULDBLOCK){ /*If the error is not caused by the non-blocking socket*/
                perror("Error in read\n");
                exit(EXIT_FAILURE);
            }
}
/*
*非阻塞套接字解决方案
*只需将读数放入for循环
*如果你想读k遍
*/
#包括
#包括
#包括
int r1;
/*将套接字设置为非阻塞*/
int flags=fcntl(sock,F_GETFL,0);
fcntl(sock、F|U SETFL、标志| O|U NONBLOCK);
errno=0/*如果读取失败,则设置errno*/
如果((r1=读取(sock,buf_in,N))=-1{/*如果读取返回错误*/
如果(errno!=EAGAIN&&errno!=ewoldblock){/*如果错误不是由非阻塞套接字引起的*/
perror(“读取错误”);
退出(退出失败);
}
}
以下是选择的解决方案:

/*
 * Select solution.
 * This is not a complete solution but
 * it's almost everything you've to do
 */


#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>

#define SVC(r,c,e)  \
    errno = 0;  \
    if((r=c)==-1) { perror(e);exit(errno); }

int r = 0;
int fd_skt;
fd_set rdset;
fd_set set;
struct timeval tv; /*Timer structure*/
int fd_num_max = 0; /*Maximum opened file descriptor*/
if(fd_skt > fd_num_max) fd_num_max = fd_skt;
FD_ZERO(set);
FD_SET(fd_skt,set); /*fd_skt is where you're waiting for new connection request*/
/*Setting the timer*/
tv.tv_sec = 0;
tv.tv_usec = 200*1000;
rdset = set;
SVC(r,select((fd_num_max+1),(&rdset),NULL,NULL,&tv),"Unable to select\n");
/*
*选择解决方案。
*这不是一个完整的解决方案,但是
*这几乎是你要做的一切
*/
#包括
#包括
#包括
#包括
#定义SVC(r、c、e)\
errno=0\
如果((r=c)=-1){perror(e);退出(errno);}
int r=0;
int fd_skt;
fd_集rdset;
fd_集;
结构时间值电视/*定时器结构*/
int fd_num_max=0/*最大打开文件描述符*/
如果(fd_skt>fd_num_max)fd_num_max=fd_skt;
FD_零点(设置);
FD_集合(FD_skt,集合)/*fd_skt是您等待新连接请求的地方*/
/*设置计时器*/
tv.tv_sec=0;
tv.tv_usec=200*1000;
rdset=set;
SVC(r,select((fd_num_max+1)、(&rdset)、NULL、NULL和tv),“无法选择\n”);

如果您的套接字是非阻塞的,您可以使用该功能。
如果套接字阻塞,可以使用函数设置读取超时。有关更多详细信息,请参阅此问题

可能是@rtur的副本,我认为这不起作用,因为这是一个在IPC@CXB关于@CXB,这是如何工作的,请阅读更多关于
n=read(sock,buffer)的内容
read()
接受3个参数。我尝试使用select,但现在它没有输出任何内容