有人能给我举一个connect()函数自定义超时的例子吗

有人能给我举一个connect()函数自定义超时的例子吗,c,sockets,networking,C,Sockets,Networking,我正在构建一个向服务器发送请求的应用程序,我需要实现一种方法来控制我尝试将()连接到服务器的时间 我想在十秒钟后结束connect()函数。我已经读过select()和非阻塞套接字,但我不完全理解它是如何工作的 有人能给我一个非常简单的例子说明如何做到这一点吗?使用C。谢谢 另外,我还想在send和recv函数中添加相同的超时 #include <stdio.h> #include <string.h> #include <sys/types.h> #incl

我正在构建一个向服务器发送请求的应用程序,我需要实现一种方法来控制我尝试将()连接到服务器的时间

我想在十秒钟后结束connect()函数。我已经读过select()和非阻塞套接字,但我不完全理解它是如何工作的

有人能给我一个非常简单的例子说明如何做到这一点吗?使用C。谢谢

另外,我还想在send和recv函数中添加相同的超时

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>  
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>

int main(void) {

struct sockaddr_in server;
int sockfd;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

server.sin_addr.s_addr = inet_addr("10.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(atoi("80"));

fcntl(sockfd, F_SETFL, O_NONBLOCK);

struct timeval tv;
fd_set writefds;

tv.tv_sec = 5;
tv.tv_usec = 500000;

FD_ZERO(&writefds);
FD_SET(sockfd, &writefds);

connect(sockfd, (struct sockaddr *)&server, sizeof(server));

if (errno == EINPROGRESS)
{
        printf("In progress");
}

select(sockfd+1, NULL, &writefds, NULL, &tv);
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空){
服务器中的结构sockaddr_;
int-sockfd;
sockfd=套接字(AF_INET,SOCK_STREAM,0);
server.sin_addr.s_addr=inet_addr(“10.0.0.1”);
server.sinu family=AF\u INET;
server.sin_port=htons(atoi(“80”);
fcntl(sockfd、F_设置FL、O_非块);
结构时间值电视;
fd_集writefds;
tv.tv_sec=5;
tv.tv_usec=500000;
FD_零(&writefds);
FD_集(sockfd和writefds);
连接(sockfd,(struct sockaddr*)和服务器,sizeof(服务器));
如果(errno==EINPROGRESS)
{
printf(“进行中”);
}
选择(sockfd+1、NULL和writefds、NULL和tv);

你能解释一下为什么errno的if条件在超时后才显示吗?这对我来说没有意义。还有,我是否应该在这里查看其他代码来正确处理这个问题。谢谢。

我给你一个提纲,而不是写实际的代码。(我假设是Linux或类似的东西。)

  • 创建套接字
  • 在插座fd上调用
    fcntl
    ,并设置
    O_NONBLOCK
    选项使套接字不阻塞。(您也可以 通过在
    socket
    打电话。)
  • 调用
    connect
    。它将立即返回。它将 可能是“失败”并出现错误
    EINPROGRESS
    ,这意味着 正在进行连接操作
  • 调用
    选择
    轮询
    等待 使套接字fd变为可写。这两个调用都具有 超时选项
  • 如果套接字变为可写(即,您的
    选择
    轮询
    
    未超时),通过调用检查连接状态
    
    getsockopt
    获取
    SO\u ERROR
    的值,该值将指示 通过返回错误代码,连接是成功还是失败 如果成功,则为0
  • 您也可以使用相同的技术来超时
    send
    s和
    recv
    s(尽管对于receive,您需要等待套接字变得可读)


    有关更多信息,请参阅以下手册页:套接字(2)、连接(2)、选择(2)、轮询(2)、套接字(7)、getsockopt(2).

    嘿,谢谢你的回答。非常有用。我在完成所有工作时仍然遇到一些问题,我已经用一些代码更新了我的问题。除非之前的系统调用返回-1,否则测试
    errno
    是不正确的。你需要以这种方式测试所有系统调用:
    socket(),fcntl(),connect(),select()
    ,…好的,谢谢。知道为什么连接之前或之后的printf语句直到超时成功后才会打印吗。我只是对发生的事情感到困惑?因为
    fcntl()
    失败,您没有进行错误检查,因此您没有发现,因此套接字仍处于阻止模式。当有人指出您的代码中存在重大错误时,“OK”不是一个适当的响应。您应该更正并重新测试。让我很快返回给您一些更新的代码。此外,我不认为fcntl失败,因为connect im当它被包含时,立即退出。但我会看看。我不会说没有错误检查被认为是我代码中的一个主要缺陷,尽管这是一个缺陷。为什么这里的人总是有聪明的话要说?