serveur_fd = socket(AF_INET, SOCK_STREAM, 0)
  • AF_INET : Famille d’adresses IPv4
  • SOCK_STREAM : Type de socket (TCP, fiable, connexion orientée flux)
  • 0 : Protocole par défaut (TCP pour SOCK_STREAM)
  • Retour : Descripteur de fichier (entier) ou -1 si erreur

Serveur TCP

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

#define PORT 8888
#define BUFFER_SIZE 1024

int main(int argc, char *argv[]) {
    int sock_fd;
    struct sockaddr_in adresse_serveur;
    struct hostent *serveur;
    char buffer[BUFFER_SIZE];
    char message[BUFFER_SIZE];
    int bytes_recus;
    struct in_addr **addr_list;  /* Pour une version plus explicite */

    /* Vérification des arguments */
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <adresse_serveur>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* 1. Création du socket */
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0) {
        perror("Erreur création socket");
        exit(EXIT_FAILURE);
    }

    /* 2. Résolution du nom d'hôte */
    serveur = gethostbyname(argv[1]);
    if (serveur == NULL) {
        fprintf(stderr, "Hôte inconnu : %s\n", argv[1]);
        close(sock_fd);
        exit(EXIT_FAILURE);
    }

    /* 3. Configuration de l'adresse */
    memset(&adresse_serveur, 0, sizeof(adresse_serveur));
    adresse_serveur.sin_family = AF_INET;
    
    /* Méthode alternative plus explicite */
    addr_list = (struct in_addr **)serveur->h_addr_list;
    adresse_serveur.sin_addr = *addr_list[0];
    adresse_serveur.sin_port = htons(PORT);

    /* 4. Connexion au serveur */
    if (connect(sock_fd, (struct sockaddr *)&adresse_serveur, sizeof(adresse_serveur)) < 0) {
        perror("Erreur connect");
        close(sock_fd);
        exit(EXIT_FAILURE);
    }

    printf("Connecté au serveur %s:%d\n", argv[1], PORT);
    printf("Adresse IP : %s\n", inet_ntoa(adresse_serveur.sin_addr));

    /* 5. Échange de données */
    while (1) {
        printf("Message à envoyer (ou 'quit' pour quitter) : ");
        fgets(message, BUFFER_SIZE, stdin);
        
        /* Suppression du saut de ligne */
        message[strcspn(message, "\n")] = '\0';
        
        if (strcmp(message, "quit") == 0) {
            break;
        }
        
        /* Envoi */
        send(sock_fd, message, strlen(message), 0);
        
        /* Réception de la réponse */
        bytes_recus = recv(sock_fd, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_recus <= 0) {
            printf("Serveur déconnecté\n");
            break;
        }
        
        buffer[bytes_recus] = '\0';
        printf("Réponse du serveur : %s\n", buffer);
    }

    /* 6. Fermeture */
    close(sock_fd);
    return 0;
}

Makefile

CC = gcc
CFLAGS = -Wall -Wextra -ansi -pedantic

all: serveur

serveur: serveur_tcp.c
	$(CC) $(CFLAGS) -o serveur serveur_tcp.c

clean:
	rm -f serveur

.PHONY: all clean

Client TCP

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

#define PORT 8888
#define BUFFER_SIZE 1024

int main(int argc, char *argv[]) {
    int sock_fd;
    struct sockaddr_in adresse_serveur;
    struct hostent *serveur;
    char buffer[BUFFER_SIZE];
    char message[BUFFER_SIZE];
    int bytes_recus;
    struct in_addr **addr_list;  /* Pour une version plus explicite */

    /* Vérification des arguments */
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <adresse_serveur>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* 1. Création du socket */
    sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_fd < 0) {
        perror("Erreur création socket");
        exit(EXIT_FAILURE);
    }

    /* 2. Résolution du nom d'hôte */
    serveur = gethostbyname(argv[1]);
    if (serveur == NULL) {
        fprintf(stderr, "Hôte inconnu : %s\n", argv[1]);
        close(sock_fd);
        exit(EXIT_FAILURE);
    }

    /* 3. Configuration de l'adresse */
    memset(&adresse_serveur, 0, sizeof(adresse_serveur));
    adresse_serveur.sin_family = AF_INET;
    
    /* Méthode alternative plus explicite */
    addr_list = (struct in_addr **)serveur->h_addr_list;
    adresse_serveur.sin_addr = *addr_list[0];
    adresse_serveur.sin_port = htons(PORT);

    /* 4. Connexion au serveur */
    if (connect(sock_fd, (struct sockaddr *)&adresse_serveur, sizeof(adresse_serveur)) < 0) {
        perror("Erreur connect");
        close(sock_fd);
        exit(EXIT_FAILURE);
    }

    printf("Connecté au serveur %s:%d\n", argv[1], PORT);
    printf("Adresse IP : %s\n", inet_ntoa(adresse_serveur.sin_addr));

    /* 5. Échange de données */
    while (1) {
        printf("Message à envoyer (ou 'quit' pour quitter) : ");
        fgets(message, BUFFER_SIZE, stdin);
        
        /* Suppression du saut de ligne */
        message[strcspn(message, "\n")] = '\0';
        
        if (strcmp(message, "quit") == 0) {
            break;
        }
        
        /* Envoi */
        send(sock_fd, message, strlen(message), 0);
        
        /* Réception de la réponse */
        bytes_recus = recv(sock_fd, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_recus <= 0) {
            printf("Serveur déconnecté\n");
            break;
        }
        
        buffer[bytes_recus] = '\0';
        printf("Réponse du serveur : %s\n", buffer);
    }

    /* 6. Fermeture */
    close(sock_fd);
    return 0;
}

Makefile

CC = gcc
CFLAGS = -Wall -Wextra -ansi -pedantic

all: client

client: client_tcp.c
	$(CC) $(CFLAGS) -o client client_tcp.c

clean:
	rm -f client

.PHONY: all clean