2013-12-16 17 views
5

Napisałem jakiś program w stylu klienta/serwera. Teraz rozwijam stronę serwera i otwieram gniazdo.Kto jest połączony na Socket w C

Ale muszę wiedzieć, kto jest podłączony w moim gnieździe. Jaki adres IP jest podłączony. Ponieważ muszę umieścić w dziennikach, którzy łączą się na serwerze.

Moje pytanie brzmi: jak mogę to zrobić w C? Korzystanie z systemu Linux.

Próbuję użyć getsockopt(), ale nie działa. I jestem nowy w programowaniu sieciowym.

Ktoś wie, jak mogę to zrobić?

Oto kod mojego gniazda:

int init_socket() { 
    /** Declara um socket */ 
    Socket sock; 

    /** Inicia o socket */ 
    sock.socket = socket(AF_INET, SOCK_STREAM, 0); 

    /** Seta zeros no sockaddr */ 
    memset(&sock.server, 0, sizeof (sock.server)); 

    /** E tambem no buffer */ 
    memset(sock.buff, 0, sizeof (sock.buff)); 

    /** Seta os valores do sockaddr */ 
    sock.server.sin_family = AF_INET; 
    sock.server.sin_addr.s_addr = htonl(INADDR_ANY); 
    //sock.server.sin_port = htons(get_config_int(&conf, "monitor_port")); 
    sock.server.sin_port = htons(2200); 

    /** Chama o bind */ 
    bind(sock.socket, (struct sockaddr*) &sock.server, sizeof (sock.server)); 

    /* 
    * É um socket blocante, então espera encher o buffer 
    * Faz o listen 
    */ 
    if (listen(sock.socket, 2) == -1) { 
     /** Deu falha na preparação para o accept, insere nos logs */ 
     insert_log(FATAL, LOG_KERNEL, "Não foi possível iniciar o socket - event.c"); 

     /** Retorna falha */ 
     return INIT_SOCKET_FAILED; 
    } 

    /** Se chegar aqui, faz o accept, dentro de um loop infinito */ 
    connect: 
    while ((sock.conn = accept(sock.socket, (struct sockaddr*) NULL, NULL))) { 
     printf("Recebi uma conexão, começando comunicação...\n"); 
     /** Agora conn é um file descriptor, podemos ler e gravar nele */ 
     while (1) { 
      if (read(sock.conn, sock.buff, sizeof (sock.buff)) == 0) { 
       close(sock.conn); 
       printf("Pronto para outra conexão...\n"); 
       goto connect; 
      } 
      printf("Eu Li isso do Buffer: %s", sock.buff); 

      /** Limpa o buffer */ 
      memset(sock.buff, 0, sizeof (sock.buff)); 
      sleep(1); 
     } 
    } 

    return INIT_SOCKET_SUCCESS; 
} 

Dzięki za pomoc!

+3

Użyj 'getpeername()'. –

+0

@ n.m .: Zamiast tego skomentuj odpowiedź. – wilx

Odpowiedz

3

accept() wezwanie daje zdalny adres jeśli przekazać adres z struct sockaddr jako argument:

struct sockaddr_storage remoteAddr; 
socklen_t remoteAddrLen = sizeof(remoteAddr); 

sock.conn = accept(sock.socket, (struct sockaddr *)&remoteAddr, &remoteAddrLen); 

można następnie przekształcić zdalny adres do łańcucha z getnameinfo(), ten współpracuje z zarówno IPv4, jak i IPv6:

char host[NI_MAXHOST]; 
getnameinfo((struct sockaddr *)&remoteAddr, remoteAddrLen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); 
1

Nie jestem pewien, czy dobrze podałem Twoje pytanie. Można użyć

struct sockaddr_in cli_addr; 

Wtedy można mieć w nieskończonej pętli kodu serwera

newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen); 

Następnie użyj inet_ntoa(), aby wyświetlić adres IP za pomocą cli_addr.

0

Może chcesz sprawdzić D.J. Tcpserver Bernsteina (patrz http://cr.yp.to/ucspi-tcp/tcpserver.html). Zasadniczo, możesz po prostu uruchomić swój program C pod tcpserver, a tcpserver zajmie się wszystkim, aż do skonfigurowania gniazd, listą połączeń przychodzących na jakimkolwiek porcie, z którego korzystasz itp. Kiedy przychodzące połączenie dotrze do określonego portu, tcpserver odrodzi instancję twojego programu i potok informacji przychodzących od klienta do STDIN twojego programu i wyśle ​​informacje o wyjściu z STDOUT twojego programu z powrotem do klienta. W ten sposób możesz skoncentrować się na głównej logice programu (i po prostu odczytać/zapisać na stdout/stdin) i pozwolić serwerowi tcpserver obsługiwać wszystkie ciężkie operacje podnoszenia aż do gniazd itp. Aby uzyskać adres IP klienta, po prostu przeczytaj Zmienna środowiskowa $ TCPREMOTEIP.

Powiązane problemy