2008-10-15 47 views
9

我有一個非常簡單的問題。我想測試一個特定的端口是否正在使用中。爲此,我想綁定一個TCP套接字到端口,如果連接被拒絕意味着端口正在使用,如果不是這意味着端口是空閒的。如何創建一個TCP套接字使用C連接到預定義的端口

有人可以告訴我如何在C編寫TCP套接字代碼?我在一個solaris平臺上。

我知道它非常基本。但我感謝你的幫助。提前致謝。

+3

這功課嗎? – 2008-10-15 11:36:33

回答

12

如果出現錯誤,則調用bind函數將返回-1。這包括地址已被使用的情況。

#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

#define PORT 12345 

int main() 
{ 
    struct sockaddr_in addr; 
    int fd; 

    fd = socket(AF_INET, SOCK_STREAM, 0); 
    if(fd == -1) 
    { 
     printf("Error opening socket\n"); 
     return -1; 
    } 

    addr.sin_port = htons(PORT); 
    addr.sin_addr.s_addr = 0; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    addr.sin_family = AF_INET; 

    if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in)) == -1) 
    { 
     printf("Error binding socket\n"); 
     return -1; 
    } 

    printf("Successfully bound to port %u\n", PORT); 
} 
-1

你可能想看看netstat的源代碼。我相信Solaris中也有一個netstat。

-1

你只想測試一下特定的端口是否正在使用? (並且不需要製作程序)。 如果是這樣,你可以使用telnet:如果連接失敗

Telnet主機端口

,它不是在使用。如果它連接並等待你的輸入,它正在使用:)

+1

這隻會告訴你該端口是否有監聽套接字,而不是它是否處於打開狀態。 – 2008-10-15 11:18:05

8

它取決於你想要測試的東西。

以joelc建議的方式使用bind()會告訴您端口是否在您的機器上的任意接口上打開。雖然要詳盡,但您不僅應該檢查bind()的返回值,還應該檢查errno == EADDRINUSE

即。 (的joelc的代碼修改)


if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in)) == -1) 
{ 
    if(errno == EADDRINUSE) 
    { 
     // handle port already open case 
    } 
    else 
    { 
     // handle other errors 
    } 
} 

通過改變在該行中使用的地址:例如。


    sin.sin_addr.s_addr = inet_addr("192.168.1.1"); 

...您可以測試一個端口是否在特定接口上可用。

請注意,這不是港口狀態的完美測試。如果另一個進程在端口正常關閉之前打開端口並終止(即在調用socket上的close()之前),那麼通常會得到相同的EADDRINUSE錯誤。 (取決於是否SO_REUSEADDR選項已經在插座上設置)

(邊注:除非你的測試程序又有足夠的權限運行,您將無法綁定()到1024以下的任何端口)

正如匿名建議,你也可以看看netstat。這將爲您提供所有與重複調用bind()所需的信息相同的信息,而且不會產生任何副作用(例如,它不必實際綁定到端口,這將使其不能用於任何其他進程)。 只需撥打netstat -a --numeric-ports -t並分析輸出應該會給你所有的東西。

對moogs建議的評論雖然 - 在每個端口上調用telnet只會告訴你,如果一個套接字在該端口上偵聽 - 而不是它是否實際打開。