Squelette de communication par socket en mode connecté pour linux

Soyez le premier à donner votre avis sur cette source.

Vue 9 993 fois - Téléchargée 498 fois

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

Ajouter un commentaire

Commentaires

Messages postés
694
Date d'inscription
lundi 5 décembre 2005
Statut
Membre
Dernière intervention
8 janvier 2014
12
Bonjour,

C'est un problème de configuration de ton réseau.
N'ayant aucune information sur le contexte d'exécution que tu as utilisé (système d'exploitation, commande de lancement du programme, etc.), et comme je ne suis pas devin, je ferais la supposition suivante : tu as lancé le récepteur avec en argument un numéro de port que la configuration de ton réseau n'autorise pas.

Il faut :
- soit utiliser un numéro de port autorisé par ta configuration réseau,
- soit modifier la configuration de ton firewall pour autoriser le numéro de port que tu as utilisé
Messages postés
2
Date d'inscription
samedi 4 mars 2006
Statut
Membre
Dernière intervention
21 avril 2008

J'ai une erreur au lancement de r :
bind(): Permission denied

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.