Squelette de communication par socket en mode connecté pour linux

Description

Un simple exemple de programme en trois fichiers.

myinet.h est un include commun pour les deux programmes
afinettcpe.c est l'émetteur
afinettcpr.c est le recepteur

Compiler chaque partie :

cc afinettcpe.c -o e
cc afinettcpr.c -o r

Lancer d'abord le récépteur, en arrière plan :
r 2 &
Lancer l'emetteur :
e localhost 2

Control-C pour arrêter.

Source / Exemple :


//
// Fichier myinet.h
//

#define MYCORPS 16
struct mymsg {
	uint32_t entete;
	char corps[MYCORPS];
};

#define BACKLOG 64

//
// Fichier afinettcpe.c
//

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include "myinet.h"

main (int argc, char *argv[]) {

	struct hostent *phost;
	int sockfd;
	struct sockaddr_in serv_addr;
	int cpt = 0;
	struct mymsg msg;
	int ret_send;
	if (argc < 3) {
		fprintf(stderr, "USAGE : afinettcpe machine_cible port_cible\n");
		exit (EXIT_FAILURE);
	}
	phost = gethostbyname(argv[1]);
	if (phost == NULL) { 
		fprintf(stderr, "Incident gethostbyname(\"%s\"p)", argv[1]);
	}

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) { perror("socket()"); exit (EXIT_FAILURE); }

	/* pour le client un bind est fait automatiquement lors du connect() */
	memset(&serv_addr, '\0', sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons((uint16_t)atoi(argv[2]));
	memcpy(&serv_addr.sin_addr, phost->h_addr, phost->h_length);
	if (connect (sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1 ) { perror ("connect()"); exit(EXIT_FAILURE); }

	while (++cpt) {
		msg.entete = htonl((uint32_t)cpt);
		strcpy (msg.corps, "Pour voir");
		ret_send = send(sockfd, &msg, sizeof(msg), 0);
		if (ret_send == -1) { perror ("send()\n"); exit(EXIT_FAILURE); }
		sleep(1);
	}  
}

//
// Fichier afinettcpr.c
//

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include "myinet.h"

main (int argc, char *argv[]) {

	int sockfd, socksrvfd;
	struct sockaddr_in my_addr, name, from;
	int fromlen;
	struct mymsg msg;
	int ret_recv;
	int cpt = 0, i, j;

	if (argc < 2) { fprintf(stderr, "Usage : afinettcpr port_reception\n"); exit (EXIT_FAILURE);}

	/* Acquisition d'un descripteur de socket. */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) { perror("socket()"); exit (EXIT_FAILURE); }

	/* assignation d'une adresse à la socket */
	memset(&my_addr, '\0', sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons((uint16_t)atoi(argv[1]));
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) { perror("bind()"); exit(EXIT_FAILURE); }
	if (listen(sockfd, BACKLOG) == -1) { perror("listen()"); exit(EXIT_FAILURE); }

	/* socket de service */
	fromlen = sizeof(from);
	memset(&from, '\0', sizeof(from));

	ecoute:
	socksrvfd = accept(sockfd, (struct sockaddr*)&from, &fromlen);
	if (socksrvfd == -1) { perror ("accept()"); exit(EXIT_FAILURE); }
	/* qui a émis */
	printf("fromlen : %d ", fromlen);
	printf("sin_family : %d ", from.sin_family);
	printf("sin_port : %d ", from.sin_port);
	printf("sin_addr : %d ", inet_ntoa(from.sin_addr));
	printf("\n");
	printf("Entrée dans la boucle de reception\n");
	while (++cpt) {
		/* lecture d'un message */
		ret_recv = recv(socksrvfd, &msg, sizeof(msg), 0);
		if (ret_recv == 0) goto ecoute;
		if (ret_recv == -1) { perror("recv()"); exit (EXIT_FAILURE); }
		/* message reçu */
		printf("cpt_serveur %d : ", cpt);
		printf("message %d - %s ",(int)ntohl(msg.entete), msg.corps);
		printf("\n");
	}  
}

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.