2008-10-15 18 views
9

Mam bardzo proste pytanie. Chcę sprawdzić, czy dany port jest aktualnie w użyciu, czy nie. W tym celu chcę powiązać gniazdo TCP z portem, jeśli połączenie zostanie odrzucone, oznacza to, że port jest w użyciu, a jeśli nie oznacza to, że port jest bezpłatny.Jak utworzyć gniazdo TCP połączyć za pomocą C do predefiniowanego portu

Czy ktoś może mi powiedzieć, jak mogę napisać kod gniazda TCP w C? Jestem na platformie Solaris.

Wiem, że to bardzo proste. Ale doceniam twoją pomoc. Z góry dziękuję.

+3

Czy to zadanie domowe? –

Odpowiedz

12

Wywołanie funkcji wiązania zwróci -1, jeśli wystąpi błąd. Obejmuje to przypadek, w którym adres jest już w użyciu.

#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

Możesz chcieć spojrzeć na kod źródłowy netstat. Wydaje mi się, że w systemie Solaris jest także netstat.

-1

Czy chcesz przetestować, czy dany port jest aktualnie używany? (i naprawdę nie trzeba tworzyć programu). Jeśli tak, można użyć telnet:

portu hosta telnet

Jeżeli połączenie nie powiedzie się, to nie jest w użyciu. Jeśli się połączy i czeka na dane od Ciebie, to jest w użyciu :)

+1

Powie Ci to tylko, czy na tym porcie znajduje się gniazdo nasłuchu, a nie czy jest otwarte. –

8

To zależy od dokładnie tego, co próbujesz przetestować.

Używanie bind() w sposób zaproponowany przez joelc powie Ci, czy port jest otwarty na dowolnym interfejsie na twoim komputerze. Chociaż należy dokładnie sprawdzić nie tylko wartość zwracaną z bind(), ale także sprawdzanie errno == EADDRINUSE.

tj. (modyfikacja kodu joelc)


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

Zmieniając adres używany w linii: np.


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

... możesz sprawdzić, czy port jest dostępny w określonym interfejsie.

Należy jednak pamiętać, że nie jest to doskonały test dla stanu portu. Jeśli inny proces miał otwarty port i został zakończony, zanim zamknie go z wdziękiem (tj. Przed wywołaniem close() na gnieździe), zazwyczaj otrzymasz ten sam błąd EADDRINUSE. (w zależności od tego, czy opcja SO_REUSEADDR został ustawiony na gnieździe)

(strona UWAGA: chyba że aplikacja jest uruchomiona Test z wystarczającymi uprawnieniami nie będzie w stanie związać() do wszelkich portów poniżej 1024)

Zgodnie z sugestią Anonymous, możesz również rzucić okiem na netstat. To da ci wszystkie te same informacje, które możesz uzyskać, wielokrotnie wywołując bind() znacznie szybciej i bez żadnych efektów ubocznych (jak to, że nie musi faktycznie wiązać się z portami, co uczyniłoby je bezużytecznymi dla jakichkolwiek innych procesów). Po prostu wywołanie netstat -a --numeric-ports -t i analizowanie danych wyjściowych powinno dać ci wszystko, czego szukasz.

Uwaga na sugestię moogów - wywołanie telnetu na każdym porcie powie ci tylko, czy gniazdo nasłuchuje na tym porcie - nie, czy faktycznie jest otwarte.