有人可以给我看一个connect()函数的自定义超时的示例

时间:2016-05-01 00:25:02

标签: c sockets networking

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

我想在十秒钟后结束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);

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

1 个答案:

答案 0 :(得分:2)

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

  1. 创建套接字。
  2. 在socket fd上调用fcntl并设置 O_NONBLOCK选项使套接字无阻塞。 (你也可能是 能够通过SOCK_NONBLOCK上的socket选项执行此操作 调用。)
  3. 致电connect。它会立即返回。它会最多 可能&#34;失败&#34;错误EINPROGRESS,这意味着 连接操作正在进行中。
  4. 致电selectpoll等待 使套接字fd变为可写。这两个电话都有一个 超时选项。
  5. 如果套接字变为可写(即,您的selectpoll 没有超时),通过调用检查连接状态 getsockopt获取SO_ERROR的值,这将表明 返回错误代码是connect成功还是失败 或成功时为0。
  6. 您也可以使用相同的技术来超时sendrecv(尽管对于接收,您需要等待套接字变得可读)。

    有关更多信息,请参见以下手册页:socket(2),connect(2),select(2),poll(2),socket(7),getsockopt(2)。