Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who is connect on Socket in C

Tags:

c

linux

sockets

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!

like image 526
Vitor Villar Avatar asked Oct 02 '22 03:10

Vitor Villar


2 Answers

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);
like image 108
Martin R Avatar answered Oct 09 '22 01:10

Martin R


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.

like image 35
Dinesh Avatar answered Oct 09 '22 00:10

Dinesh