Vitor Villar
Vitor Villar

Reputation: 1925

Who is connect on Socket in C

i'm write some program in client/server style. Now i'm developing the server side, and i open an socket.

But, i need to know who is connected in my socket. What IP is connected. Because i need to put in logs who connect on server.

So, my question is how can i do this in C? Using Linux.

I try to use getsockopt() but don't work. And i'm new on network programming.

Someone know how can i do this?

Here is the code of my socket:

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

Thanks for help!

Upvotes: 5

Views: 484

Answers (4)

yuxing
yuxing

Reputation: 47

I thought you could try getpeername(2) and inet_ntoa(3). http://linux.die.net/man/2/getpeername, http://linux.die.net/man/3/inet_ntoa

Upvotes: 0

mti2935
mti2935

Reputation: 12027

You may want to check out D.J. Bernstein's tcpserver (see http://cr.yp.to/ucspi-tcp/tcpserver.html). Basically, you can simply run your C program under tcpserver, and tcpserver will handle everything as far as setting up the sockets, listing for incoming connections on whatever port you are using, etc. When an incoming connection arrives on the port that you specify, tcpserver will spawn an instance of your program and pipe incoming info from the client to your program's STDIN, and pipe outgoing info from your program's STDOUT back to the client. This way, you can concentrate on your program's core logic (and simply read/write to stdout/stdin), and let tcpserver handle all of the heavy lifting as far as the sockets, etc. To get the client's IP address, just read the $TCPREMOTEIP environment variable.

Upvotes: 0

Dinesh
Dinesh

Reputation: 2204

I am not sure if I got your question right. You can use

struct sockaddr_in cli_addr;

Then you can have an in the infinite loop of the server code

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

Then use inet_ntoa() to display the IP address using cli_addr.

Upvotes: 1

Martin R
Martin R

Reputation: 539815

The accept() call gives you the remote address if you pass the address of a struct sockaddr as argument:

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

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

You can then convert the remote address to a string with getnameinfo(), this works with both IPv4 and IPv6:

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

Upvotes: 3

Related Questions