如何检查远程主机是否可以在C语言中的特定端口访问?

如何检查远程主机是否可以在C语言中的特定端口访问?,c,sockets,C,Sockets,我正在编写一个C程序来检查远程主机是否响应特定端口(在我的例子中,应用程序运行在远程端的9090上)。起初我试过 nc-zv使用system()函数调用,但无法获得所需的结果。 现在,我创建了一个非阻塞套接字,并使用connect()调用对其进行检查。但其返回值为-1,设置为errno-115(操作正在进行中) 在网上搜索之后,我想到了使用select()和poll(),但我不知道如何实现这些。 任何关于示例程序的建议都会很有帮助。严格执行您正在执行的操作,但要使用阻塞模式 或者,完全按照您正在

我正在编写一个C程序来检查远程主机是否响应特定端口(在我的例子中,应用程序运行在远程端的9090上)。起初我试过
nc-zv
使用system()函数调用,但无法获得所需的结果。 现在,我创建了一个非阻塞套接字,并使用connect()调用对其进行检查。但其返回值为-1,设置为errno-115(操作正在进行中) 在网上搜索之后,我想到了使用
select()
poll()
,但我不知道如何实现这些。
任何关于示例程序的建议都会很有帮助。

严格执行您正在执行的操作,但要使用阻塞模式

或者,完全按照您正在执行的操作,然后将套接字FD添加到writeFDs集合,并调用
select()。
如果FD显示为可写,则连接成功

别忘了关上插座


但我想知道你为什么要这么做。只要试着连接到你需要连接的任何东西,在你需要连接的时候。不要试图预测它是否会成功。

我的理解是,你只会做一个简单的连接。应在blockig模式下执行此操作。 这里有一个例子:

#include <netdb.h>
#include <arpa/inet.h>
#include <sys/un.h>

in_addr_t in_build_addr(const char * p_server)
{
  in_addr_t addr = inet_addr(p_server);
  if(INADDR_NONE == addr) {
    struct hostent * server_info = gethostbyname(p_server);
    if(NULL == server_info) {
      return 0;
    }
    memcpy(&addr, server_info->h_addr_list[0], server_info->h_length);
  }
  return addr;
}

int check_connect(const char * p_server, in_port_t p_port) {
  int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if(0 > sock) {
    return -1;
  }
  struct sockaddr_in addr = {
      .sin_family       = AF_INET,
      .sin_port         = htons(p_port),
      .sin_addr.s_addr  = in_build_addr(p_server)
    };
  if(0 != connect(sock, (struct sockaddr *)&addr, sizeof(addr))) {
    close(sock);
    return -2;
  }
  close(sock);
  return 0;
}
#包括
#包括
#包括
in_addr_t in_build_addr(const char*p_服务器)
{
in_addr_t addr=inet_addr(p_服务器);
if(INADDR_NONE==addr){
结构hostent*server\u info=gethostbyname(p\u服务器);
if(NULL==服务器信息){
返回0;
}
memcpy(&addr,server\u info->h\u addr\u list[0],server\u info->h\u length);
}
返回地址;
}
int check_connect(const char*p_服务器,in_端口t p_端口){
int sock=socket(PF_INET、sock_STREAM、IPPROTO_TCP);
如果(0>sock){
返回-1;
}
地址中的结构sockaddr\u={
.sin_family=AF_INET,
.sin_port=htons(p_port),
.sin_addr.s_addr=in_build_addr(p_服务器)
};
如果(0!=connect(sock,(struct sockaddr*)&addr,sizeof(addr))){
关闭(袜子);
返回-2;
}
关闭(袜子);
返回0;
}

您可以尝试使用功能检查连接。此函数连接到给定的服务器(ip或名称)和端口,并立即关闭套接字。

是否有任何方法可以指定connect()调用的超时。我的意思是connect()将在阻塞modeIIRC中尝试数秒,connect()超时是大多数操作系统上的一个系统范围参数,并假设对等方可能位于三个卫星链路和两个调制解调器(即,非常长:)之后。@cbinder No。您必须使用
select()
。请注意,您只能减少而不能增加平台连接超时。无法为
connect()
指定超时。您必须在非阻塞模式下进行连接,并使用
select()
(e)poll()
检测超时/结果。@EJP到目前为止工作正常,但现在阻塞模式下的connect()大约需要20秒才能返回无法访问的主机状态。我需要尽快赶回来。现在,当我使用select()并将超时设置为0时,它无法检测连接(返回0),而在设置超时时(我尝试了5秒),它可以工作。安全值是多少?还有其他方法吗。