首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定ip地址是否可访问的最佳快速方法

问确定ip地址是否可访问的最佳快速方法
EN

Stack Overflow用户
提问于 2009-12-24 05:28:52
回答 5查看 7K关注 0票数 1

我需要最快的方法来查看ip地址是否可达。在每个ip地址上都有一个服务器在监听一个特定的端口,所以如果你的方法要找出一个服务器是否在监听一个端口,请告诉我。

这样做的原因是,假设我有10个ip地址,其中10个服务器在每个ip地址上监听端口101。我希望我的客户端能够找到一个可访问的ip地址,并尽可能快地连接到它(我不想让他等待30秒来找出一个ip地址是否可访问,然后再尝试列表中的下一个ip地址)

也许它必须同时在踏面上完成。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-12-24 05:45:29

虽然您可以快速确定IP是否可达,但您的问题在于确定IP不可达。原因是您不能总是明确地确定IP是不可访问的。虽然在某些情况下,您将得到IP不可达的肯定通知,但通常情况下,您的代码将不会听到回答,并且在等待一段时间后,您的代码将假定IP不可达。

决定超时的问题是网络拓扑。如果你有一个大的拓扑结构(比如Internet),当你试图连接到一个‘遥远’的IP时,你将需要一个很大的超时时间来处理潜在的高延迟。

根据您的描述,最好的想法是尝试同时连接到所有服务器,并使用第一个接受连接的服务器。您可以使用线程,也可以使用非阻塞套接字。在非阻塞的connect中,connect调用立即返回,然后您可以使用select有效地确定connect调用何时完成(成功或出错)。

票数 3
EN

Stack Overflow用户

发布于 2009-12-24 06:38:06

您可以使用线程,但这将为此任务带来不必要的开销。

在这里使用非阻塞套接字(尽可能避免使用非阻塞套接字!真的,但在这种情况下它们是有意义的):

代码语言:javascript
复制
// initiate tcp connects...
for( each of your target host+port pairs ) {
    int socket = socket( AF_INET, SOCK_STREAM );
    ...
#ifdef WIN32
    unsigned long mode = 1;
    ioctlsocket( socket, FIONBIO, &mode );
#else
    int value = fcntl( socket, F_GETFL, 0 );
    fcntl( socket, F_SETFL, value | O_NONBLOCK );
#endif
    ...
    int code = connect( s, target, ... );
    if( code == 0 ) { /* ok, this one did connect, DONE */ }
    // now remember the socket in a list ...
}
// now find the first socket that was successfully connected
while( still not found ) {
    struct timeval tval;
    memset( &tval, 0, sizeof(tval) );
    fd_set write_set, error_set;
    int largest_socket = 0;
    // add sockets to write and error set, and determine largest socket no.
    for( each socket that did not fail until now ) {
        FD_SET( socket, write_set );
        FD_SET( socket, error_set );
        if( socket > largest_socket ) largest_socket = socket;
    }
    // now use select to wait until something happens on the sockets
    int code = select( largest_socket+1, NULL, &write_set, &error_set, &tval );
    if( code < 0 ) { something went terribly wrong }
    else {
        for( each socket that did not fail until now ) {
            if( FD_ISSET( socket, write_set ) ) { you've found it! DONE }
            if( FD_ISSET( socket, error_set ) ) { error, remove this socket from list (for next iteration) }
        }
    }
}

有关更多详细信息,请查看connect和select文档!

票数 3
EN

Stack Overflow用户

发布于 2009-12-24 05:33:56

通常,随机尝试与短时间的连接就足够了。

可达性并不是很重要,从你到服务器的路由是否存在并不重要,重要的是你是否能连接到服务器。通常,您自己的代码运行速度与您可以设计的任何其他可达性方法一样快。

如果你对它花费的时间太长有问题,那么试着调整响应的长度,或者有更严格的超时。

简单的算法:

代码语言:javascript
复制
shuffle IP addresses
foreach IP in addresses
    attempt connect
    if succeed then
       break
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1955420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档