【问题标题】:Socket Timeout in C++ LinuxC++ Linux 中的套接字超时
【发布时间】:2010-10-30 07:22:10
【问题描述】:

好的,首先我想提一下我所做的事情是完全合乎道德的,是的,我正在扫描端口。

当端口打开时程序运行良好,但是当我到达关闭的套接字时,程序会暂停很长时间,因为没有超时条款。下面是下面的代码

int main(){

    int err, net;
    struct hostent *host;
    struct sockaddr_in sa;

    sa.sin_family = AF_INET;

    sa.sin_port = htons(xxxx);
    sa.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");

    net = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    err = connect(net, (struct sockaddr *)&sa, sizeof(sa));

    if(err >= 0){ cout << "Port is Open"; }
    else { cout << "Port is Closed"; }

}

我在堆栈溢出时发现了这一点,但使用select() 命令对我来说没有意义。

问题是我们是否可以让 connect() 函数超时,这样我们就不用等一年就让它返回错误?

【问题讨论】:

  • 不需要解释你为什么需要它——这就像问银行的方向,每次都解释你想取钱而不是抢劫......
  • :D 说得好。但我没有取款:D

标签: c++ linux sockets timeout


【解决方案1】:

最简单的方法是设置alarm 并让connect 被信号中断(参见UNP 14.2):


signal( SIGALRM, connect_alarm ); /* connect_alarm is you signal handler */
alarm( secs ); /* secs is your timeout in seconds */
if ( connect( fs, addr, addrlen ) < 0 )
{
    if ( errno == EINTR ) /* timeout */
        ...
}
alarm( 0 ); /* cancel alarm */

虽然使用select 并不难:)
您可能也想了解raw sockets

【讨论】:

  • 谢谢,这很管用,我必须查看警报器和信号器才能了解它是如何工作的,但无论如何,它可以满足我在锡罐上的要求。谢谢:D
  • sigaction 通常应优先于 signal,后者在不同的 UNIX 上具有不同的行为。
  • @Shahmir Javaid:你成功发出 connect_alarm 了吗?我正在看到它,但我不明白它是如何工作的......
  • 我有一个应用程序可以连接到不同的端点。将这种alarm()方法用于一个端点连接时,超时是否也会引起其他连接的警报?
【解决方案2】:

如果您执着于使用阻塞 IO 来完成这项工作,您应该调查 setsockopt() 调用,特别是 SO_SNDTIMEO 标志(或其他标志,取决于您的操作系统)。

请注意,这些标志不可靠/不便携,并且可能在不同平台或给定平台的不同版本上以不同方式实现。

执行此操作的传统/最佳方法是通过使用 select() 的非阻塞方法。如果您不熟悉套接字,最好的书籍之一是 TCP/IP Illustrated, Volume 1: The Protocols。它在亚马逊上:http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

【讨论】:

    【解决方案3】:

    RudeSocket 解决了问题

    我发现了一个在 linux Fedora(不确定 Windows)中测试的 lib 文件,它给了我超时选项。您可以在下面找到一个非常简单的示例。

    #include <rude/socket.h>
    #include <iostream>
    
    using namespace std;
    using namespace rude;
    
    Socket soc;
    soc.setTimeout(30, 5);
    
    //Try connecting
    if (soc.connect("xxx.xxx.xxx.xxx", 80)){
    
        cout << "Connected to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
    }
    
    //connections Failed
    else{
        cout << "Timeout to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
    }
    
    soc.close();
    

    这是DevSite的链接

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 2013-12-24
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多