设置接收函数的套接字超时时间。

3

我有一个客户端到服务器的连接,其中客户端正在向服务器发送数据。

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

问题是我只想等待一些秒钟来进行读取 - 在我的代码中,如果客户端没有发送任何内容,它就会被卡在等待服务器读取某些内容的地方。

请问我该如何等待几秒钟以后再进行读取呢?


4
可能是 如何在读取函数调用中实现超时? 的重复问题。 - rtur
@rtur我认为这不会起作用,因为这是在IPC中读取的内容。 - CXB
1
@CXB 这个怎么样?(https://dev59.com/fXE85IYBdhLWcg3wOw_s) - Gaurav Pathak
@CXB 这个可行,了解更多关于非阻塞套接字的内容。 - Pravin
3
n = read(sock, buffer); 这行代码表示从套接字(socket)中读取数据,并将结果存储在缓冲区(buffer)中,读取的字节数将被赋值给变量n。read()函数有三个参数。 - Andrew Henle
3个回答

3

1
您可以使用select() API来实现此目的。在此API中,您可以在秒和微秒中指定时间。

我尝试使用select,但现在它没有输出任何内容。 - CXB

1
基本上,read调用尝试读取数据,因此如果您不想在其上卡住,您需要将sock变量声明为非阻塞或使用带有超时的select函数(man select)。在第一种情况下,您不能等待几秒钟,但可以尝试读取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);
            }
}

这是一个选择解决方案:

/*
 * 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");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接