UNIX & GNU/Linux - System calls - Using listen()

The listen() system call is designed to tell that a socket is ready to accept incoming connection.

Of course, we need first implementing the socket() and bind() system calls.

We are talking here about the server side.

Let's see how to use the listen() system call with this tutorial.

Using listen()

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

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);
    debug(&s);
    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\n", s->listenValue);
}

void check_error(int test, int error)
{
    if (test == error)
    {
        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

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

    int sockfd;
    socklen_t addrlen;
    struct sockaddr_in addr;
    int bindValue;

    int listenValue;
} t_s;

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

#endif /* H_H_ */

Compiling

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

Result

===== 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

Great! surprise

Add new comment

Plain text

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