2013-12-16 11 views
5

Sto scrivendo qualche programma in stile client/server. Ora sto sviluppando il lato server e apro un socket.Chi è connesso su Socket in C

Ma, ho bisogno di sapere chi è collegato nella mia presa. Quale IP è connesso. Perché ho bisogno di mettere i registri che si connettono sul server.

Quindi, la mia domanda è come posso fare questo in C? Usare Linux.

Provo ad utilizzare getsockopt() ma non funzionano. E io sono nuovo sulla programmazione di rete.

Qualcuno sa come posso fare questo?

Ecco il codice della mia presa:

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; 
} 

Grazie per l'aiuto!

+3

Utilizzare 'getpeername()'. –

+0

@ n.m .: Dai il tuo commento una risposta. – wilx

risposta

3

La chiamata accept() ti dà l'indirizzo remoto se si passa l'indirizzo di un struct sockaddr come argomento:

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

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

È quindi possibile convertire l'indirizzo remoto di una stringa con getnameinfo(), questo funziona con sia IPv4 che IPv6:

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

Non sono sicuro di aver risposto correttamente alla domanda. È possibile utilizzare

struct sockaddr_in cli_addr; 

allora si può avere una nel ciclo infinito del codice del server

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

Quindi utilizzare inet_ntoa() per visualizzare l'indirizzo IP utilizzando cli_addr.

0

Si consiglia di controllare D.J. Tcpserver di Bernstein (vedere http://cr.yp.to/ucspi-tcp/tcpserver.html). Fondamentalmente, puoi semplicemente eseguire il tuo programma C su tcpserver e tcpserver gestirà tutto fino alla configurazione dei socket, elencando le connessioni in entrata su qualsiasi porta in uso, ecc. Quando una connessione in arrivo arriva sulla porta che hai specificato, tcpserver genererà un'istanza del tuo programma e reindirizzerà le informazioni in arrivo dal client allo STDIN del tuo programma e condurrà le informazioni in uscita dallo STDOUT del tuo programma al client. In questo modo, puoi concentrarti sulla logica di base del tuo programma (e semplicemente leggere/scrivere su stdout/stdin), e lasciare che tcpserver gestisca tutto il carico pesante fino ai socket, ecc. Per ottenere l'indirizzo IP del client, leggi il $ Variabile d'ambiente TCPREMOTEIP.