2016-11-18 148 views
0

我的任務是檢查IP是否存在或不存在。所以我跟着這個link和修改的代碼如下所示...呼叫連接需要太多時間

int isServerAlive(const char* serverAdd) 
{ 
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    struct sockaddr_in sin; 
    sin.sin_family = AF_INET; 
    sin.sin_port = htons(65432); // Could be anything. 
    inet_pton(AF_INET, serverAdd, &sin.sin_addr); 

    if (connect(sockfd, (struct sockaddr *) &sin, sizeof(sin)) == -1) 
    { 
     // The two main errors you get if the host is dead are ENETUNREACH and ETIMEDOUT. 
     if (errno == ENETUNREACH || errno == ETIMEDOUT) 
     { 
      printf("Error connecting %s: %d (%s)\n",serverAdd, errno, strerror(errno)); 
      return FAILURE; 
     } 
    } 
    return SUCCESS; 
} 

當我嘗試執行該代碼,連接調用花費過多時間。

  • 我在這裏做錯了什麼嗎?
  • 有沒有其他更好的方法來檢查IP是否存活?

在此先感謝。

+0

可能是防火牆問題? – NJMR

+0

_ ** //可能是任何東西。** _不正確。這取決於您的平臺,並取決於您的服務器端套接字配置 – LPs

回答

1

如果連接嘗試超時,則網絡堆棧將再次嘗試幾次。等待一段時間,不幸的是重試需要時間。

基本上有兩種方式來解決這個問題:

  1. 使用非阻塞套接字。然後connect調用返回有效連接。它將返回一個錯誤並且errno設置爲EINPROGRESS。如connect手冊頁所述,您可以使用例如select查看套接字是否可寫以知道連接嘗試已完成,並且您可以獲取狀態。

  2. 第二種解決方案是使用線程。然後,當您的主線程執行其他操作時,連接嘗試可以在後臺運行。

+0

我正在測試的服務器處於活動狀態,並且連接調用正在獲取超時。即使我使用非阻塞套接字,它仍然會超時。我對嗎? – NJMR

+0

@NJMR如果服務器處於活動狀態,但無法訪問它,那麼可能是防火牆問題。此外,如果您使用非阻塞套接字,那麼如果連接超時,您將得到與使用阻塞套接字相同的錯誤。您只需檢查狀態並以不同的方式獲取錯誤。這一切都在[手冊頁]中解釋過(http://man7.org/linux/man-pages/man2/connect.2.html)。 –

+0

還有一件事:我必須測試的所有服務器(Aliver或不)都支持ping。我可以使用ping命令來達到同樣的目的嗎? – NJMR

1

如果是,你知道服務器會響應平,你一定要使用做檢測。假設您的服務器位於代理或NAT後面,可以輕鬆擊敗您的SYN檢測。

在Linux環境下,一個ping檢測機制應該是這樣的:

system("ping xx.xx.xx.xx -c 3 -i 1 -W 3 -q > /tmp/ping-xx.xx.xx.xx.log &");

6秒後,你可以打開該文件,並解析平的結果:

3包0收到,100%丟包,時間2039ms

Note: 
       -c 3: only issue 3 ping packets 
       -i 1: send packets at 1 second interval 
       -W 3: wait response up to 3 seconds, so the total time should no more than 3 + 3 = 6 seconds 
       -q: suppress no needed information. 

這些ping參數只是服務器的例子,你應該根據你的真實環境來定製它們。

+0

我沒有寫日誌然後解析日誌的自由。我可以在同一個流程中完成嗎? – NJMR

+0

您可以改用popen/pclose。 – user2760751