我有一个简单的程序来判断端口是否打开,但是我想缩短套接字连接的超时长度,因为缺省值太长了.不过,我不知道该怎么做.以下是代码:

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

int main(int argc, char **argv) {
    u_short port;                /* user specified port number */
    char addr[1023];             /* will be a copy of the address entered by u */
    struct sockaddr_in address;  /* the libc network address data structure */
    short int sock = -1;         /* file descriptor for the network socket */

    if (argc != 3) {
        fprintf(stderr, "Usage %s <port_num> <address>", argv[0]);
        return EXIT_FAILURE;
    }

    address.sin_addr.s_addr = inet_addr(argv[2]); /* assign the address */
    address.sin_port = htons(atoi(argv[2]));            /* translate int2port num */

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (connect(sock,(struct sockaddr *)&address,sizeof(address)) == 0) {
        printf("%i is open\n", port);
    }  
    close(sock);
    return 0;
}

推荐答案

本文可能有助于:

Connect with timeout (or another use for select() )

看起来您将套接字置于非阻塞模式,直到连接完成,然后在连接建立后将其重新置于阻塞模式.

void connect_w_to(void) { 
  int res; 
  struct sockaddr_in addr; 
  long arg; 
  fd_set myset; 
  struct timeval tv; 
  int valopt; 
  socklen_t lon; 

  // Create socket 
  soc = socket(AF_INET, SOCK_STREAM, 0); 
  if (soc < 0) { 
     fprintf(stderr, "Error creating socket (%d %s)\n", errno, strerror(errno)); 
     exit(0); 
  } 

  addr.sin_family = AF_INET; 
  addr.sin_port = htons(2000); 
  addr.sin_addr.s_addr = inet_addr("192.168.0.1"); 

  // Set non-blocking 
  if( (arg = fcntl(soc, F_GETFL, NULL)) < 0) { 
     fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno)); 
     exit(0); 
  } 
  arg |= O_NONBLOCK; 
  if( fcntl(soc, F_SETFL, arg) < 0) { 
     fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno)); 
     exit(0); 
  } 
  // Trying to connect with timeout 
  res = connect(soc, (struct sockaddr *)&addr, sizeof(addr)); 
  if (res < 0) { 
     if (errno == EINPROGRESS) { 
        fprintf(stderr, "EINPROGRESS in connect() - selecting\n"); 
        do { 
           tv.tv_sec = 15; 
           tv.tv_usec = 0; 
           FD_ZERO(&myset); 
           FD_SET(soc, &myset); 
           res = select(soc+1, NULL, &myset, NULL, &tv); 
           if (res < 0 && errno != EINTR) { 
              fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno)); 
              exit(0); 
           } 
           else if (res > 0) { 
              // Socket selected for write 
              lon = sizeof(int); 
              if (getsockopt(soc, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) { 
                 fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno)); 
                 exit(0); 
              } 
              // Check the value returned... 
              if (valopt) { 
                 fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt) 
); 
                 exit(0); 
              } 
              break; 
           } 
           else { 
              fprintf(stderr, "Timeout in select() - Cancelling!\n"); 
              exit(0); 
           } 
        } while (1); 
     } 
     else { 
        fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno)); 
        exit(0); 
     } 
  } 
  // Set to blocking mode again... 
  if( (arg = fcntl(soc, F_GETFL, NULL)) < 0) { 
     fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno)); 
     exit(0); 
  } 
  arg &= (~O_NONBLOCK); 
  if( fcntl(soc, F_SETFL, arg) < 0) { 
     fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno)); 
     exit(0); 
  } 
  // I hope that is all 
}

C++相关问答推荐

两个看似相同的代码的不同行为

rSP堆栈指针在返回函数调用的值时有任何用途吗?

Tiva TM4C123GXL的I2C通信

创建一个fork导致fget无限地重新读取文件

不会停在空格或换行符上的错误

C是否用0填充多维数组的其余部分?

如何创建一个C程序来存储5种动物的名字,并在用户 Select 其中任何一种动物时打印内存地址?

自定义变参数函数的C预处置宏和警告 suppress ?

具有交换链获取和命令缓冲区提交的同步-危险-读后写错误

如何使用[BTStack]BLE发送大型(>;2kb)信息包

我的C函数起作用了,但我不确定为什么

预处理器宏扩展(ISO/IEC 9899:1999(E)§;6.10.3.5示例3)

将数组插入数组

我应该在递归中使用全局变量吗

不使用任何预定义的C函数进行逐位运算

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

为什么一个在线编译器拒绝这个VLA代码,而本地的Apple clang却不拒绝;t?

通过GTK';传递回调参数;s g_signal_connect()导致C中出现意外值

获取 struct 中匿名 struct 的大小