C - Library functions - Using inet_ntoa()

The inet_ntoa() function C returns the address of a client side, for example.

We give to the unique inet_ntoa() parameter, a struct in_addr.
We can then retrieve the address of this parameter.

Let's look it in this tutorial with an example of code.

Using inet_ntoa()

server.c

/* server.c */
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>


#include "h.h"

void my_socket(t_s *s)
{
    s->name    = "TCP";
    s->domain    = AF_INET;
    s->type    = SOCK_STREAM;
    s->pe        = getprotobyname(s->name);
    s->fd        = socket(s->domain, s->type, s->pe->p_proto);
    check_error(s->fd, -1);
}

void my_bind(t_s *s, int port)
{
    s->sockfd                = s->fd;
    s->addr.sin_family        = s->domain;
    s->addr.sin_addr.s_addr = INADDR_ANY;
    s->addr.sin_port        = htons(port);
    s->addrlen                = sizeof(s->addr);
    s->bindValue            = bind(s->fd, (const struct sockaddr *)&s->addr, s->addrlen);
    check_error(s->bindValue, -1);
}

void my_listen(t_s *s, int backlog)
{
    s->listenValue = listen(s->sockfd, backlog);
    check_error(s->listenValue, -1);
}

void my_accept(t_s *s)
{
    s->addrlenAccept = sizeof(s->addrAccept);
    s->acceptValue = accept(s->sockfd, (struct sockaddr *)&s->addrAccept, &s->addrlenAccept);
    check_error(s->acceptValue, -1);
    s->acceptAddr = inet_ntoa(s->addrAccept.sin_addr);
    check_null(s->acceptAddr);
}

int main(int ac, char *av[])
{
    t_s s;

    check_arg(ac, ARG_SIZE);
    my_socket(&s);
    my_bind(&s, atoi(av[1]));
    my_listen(&s, BACKLOG);
    my_accept(&s);
    debug(&s);
    check_error(close(s.acceptValue), -1);
    check_error(close(s.fd), -1);
    return 0;
}

debug.c

/* debug.c */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include "h.h"

void debug(t_s *s)
{
    printf("\n===== socket() =====\n");
    printf("domain = %d\n", s->domain);
    printf("type = %d\n", s->type);
    printf("fd = %d\n", s->fd);
    printf("name = %s\n", s->name);
    printf("p_proto = %d\n", s->pe->p_proto);

    printf("\n===== bind() =====\n");
    printf("sockfd = %d\n", s->sockfd);
    printf("sin_family = %d\n", s->addr.sin_family);
    printf("sin_addr.s_addr = %d\n", s->addr.sin_addr.s_addr);
    printf("sin_port = %d\n", s->addr.sin_port);
    printf("addrlen = %d\n", s->addrlen);
    printf("bindValue = %d\n", s->bindValue);

    printf("\n===== listen() =====\n");
    printf("listenValue = %d\n", s->listenValue);

    printf("\n===== accept() =====\n");
    printf("addrlenAccept = %d\n", s->addrlenAccept);
    printf("acceptValue = %d\n", s->acceptValue);
    printf("s->acceptAddr = %s\n\n", s->acceptAddr);
}

void check_error(int test, int error)
{
    if (test == error)
    {
        fprintf(stderr, "ERROR: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
}

void check_null(char *test)
{
    if (test == NULL)
    {
        fprintf(stderr, "ERROR: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
}

void check_arg(int ac, int number)
{
    if (ac < number)
    {
        printf("Usage: ./server [PORT]\n");
        exit(EXIT_FAILURE);
    }
}

h.h

#ifndef H_H_
#define H_H_

#include <netdb.h>

/**
 * Define
 */
#define ARG_SIZE 2
#define BACKLOG 10
#define BUF_SIZE 255

/**
 * Structure
 */
typedef struct mystruct
{
    /* socket */
    int domain;
    int type;
    int fd;
    char *name;
    struct protoent *pe;

    /* bind */
    int sockfd;
    socklen_t addrlen;
    struct sockaddr_in addr;
    int bindValue;

    /* listen */
    int listenValue;

    /* accept */
    int acceptValue;
    socklen_t addrlenAccept;
    struct sockaddr_in addrAccept;
    char *acceptAddr;

    /* read & write */
    int readValue;
    int writeValue;
    char buf[256];
} t_s;

/**
 * Prototype
 */
void debug(t_s *);
void check_error(int, int);
void check_null(char *);
void check_arg(int, int);

#endif /* H_H_ */

Compiling

$ gcc server.c debug.c -o server ; ./server 5000

Now that the server is launched, it's waiting a connection from a client on the port 5000.

For that we need to start another shell (it will be our client side).
We have to specified the address and the port.
As we are in local (on our system), we can use the localhost alias or if it doen't work, its real value : 127.0.0.1.

So let's type with nc:

$ nc localhost 5000

Result

At the end of the display, we can see the IP of our client.

===== socket() =====
domain = 2
type = 1
fd = 3
name = TCP
p_proto = 6

===== bind() =====
sockfd = 3
sin_family = 2
sin_addr.s_addr = 0
sin_port = 34835
addrlen = 16
bindValue = 0

===== listen() =====
listenValue = 0

===== accept() =====
addrlenAccept = 16
acceptValue = 4
s->acceptAddr = 127.0.0.1

Good one! yes

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.