2009-05-31 76 views
8

好的首先,我想提一下我所做的是完全合乎道德的,而且我是端口掃描。在C++ Linux中的套接字超時

當端口打開時程序運行正常,但當我到達一個關閉的套接字時,程序停止很長時間,因爲沒有超時條款。下面是下面的代碼

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()函數超時,所以我們不會等一年纔會返回一個錯誤?

+14

沒有必要,爲什麼你需要它來解釋 - 這就像問路銀行和每一個解釋要取錢,而不是搶它的時間.. – stefanB 2009-06-01 00:19:26

+1

:D很好。但沒有即時提款:D – 2009-06-01 13:26:47

回答

7

最簡單的是建立一個alarmconnect與信號中斷(見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太。

+1

謝謝,這工作,我不得不看看警報和信號的東西,瞭解如何工作,但沒有更少的,這是我所問的錫。感謝:D – 2009-06-01 13:25:32

2

如果你使用阻塞IO來完成這個工作,你應該調查setsockopt()調用,特別是SO_SNDTIMEO標誌(或其他標誌,取決於你的操作系統)。

預先警告這些標誌不可靠/便攜,並且可能在不同平臺或給定平臺的不同版本上以不同方式實現。

傳統/最好的方法是通過使用select()的非阻塞方法。如果你不熟悉socket,最好的書籍之一是TCP/IP Illustrated,第1卷:The Protocols。這是亞馬遜在:http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

1

RudeSocket解決了這個問題

我發現,在Linux中的Fedora測試一個lib文件(不知道有關Windows),讓我超時選項。在下面你可以找到一個非常簡單的例子。

#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