Soket sous LINUX

Résolu
diablo31170 Messages postés 17 Date d'inscription mercredi 15 mai 2013 Statut Membre Dernière intervention 13 juin 2006 - 10 mai 2006 à 15:49
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 - 11 mai 2006 à 20:18
Bonjour à tous le monde,

comme le nom l'indique, cela va parler de soscket sous linux (en C++). Il aut savoir que je travaille en mode connecté.

Je cherche un programme permettant de dialoguer entre deux application
entre deux PC ; un client et un serveur (une application par PC).



J'ai lu les méthodes a utiliser :

- Création de la socket : sockaddr_in //initialise la socket

- Identifiaction de la station du serveur avec struct hostent gethostbyname(* name)

- Création de la socket : socket(domaine, type, protocole)

- demande de la connection : int connect (sock, adrss,lg_ag)
- dialogue serveur/client :

- fermeture de la socket :



Les questions que je me pose sont :

- Je ne connait pas la fonction pour fermet la socket ?

- pour dialoguer serveur/client, il faut juste utilisé les fonctions recv() et send() ?

- Faut il faire un attachement de la soket avec la fonction bind() ?



Merci de vos réponses futures et a bientot

13 réponses

turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
11 mai 2006 à 20:18
Si tu veux te servir des string en C, c mort.
String est une class de la STL, utilisé en C++. En C++ tu a besoin d'un include pour utiliser les string : .
Mais ne compte pas pouvoir t'en servir en C, il faut que tu utilise ce bon vieu char.

De plus fprintf ne marche pas, c'est printf("Taper votre trame \n"); ou fprintf(stdout,"Taper votre trame \n");

#define MAX_SIZE 65535

char a[MAX_SIZE] = " ";
ou
char* a=(char*)malloc(sizeof(char)*MAX_SIZE)

printf("Taper votre trame \n");
scanf("%s",a)
fflush(stdin);
strcpy(msg.corps, a);

TuRn3r
3
zytry Messages postés 12 Date d'inscription mardi 7 janvier 2003 Statut Membre Dernière intervention 12 septembre 2006
10 mai 2006 à 16:42
1. Pour fermer la socket : close(descripteur);

2. Pour le dialogue, tu peux utiliser read et write (en TCP), aucune idee pour recv et send mais je crois que ça marche (a confirmer)

3. Pour le bind, tu dois le faire explicitement pour le serveur, mais il sera fait implicitement pour le client

Petite remarque, gethostbyname() n'est pas necessaire, tu peux ecouter sur toutes les interfaces en faisant serveur_adr.sin_addr.s_addr INADDR_ANY;, ou sinon inet_addr("127.0.0.1"); suffit
0
zytry Messages postés 12 Date d'inscription mardi 7 janvier 2003 Statut Membre Dernière intervention 12 septembre 2006
10 mai 2006 à 16:44
ola, on dirait qu'il aime pas mes sauts de ligne...
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
10 mai 2006 à 17:15
Bonjour,

Voila un petit squelette de communication par socket en mode connecté :

myinet.h :

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

#define BACKLOG 64

recepteur :

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

emetteur :

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

Pour la fermeture de socket. Il s'agit d'un fichier comme un autre. Une ressource du programme qui sera libérée avec toutes les autres. Il n'est pas necessaire de faire un close, s'il n'est pas utile.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
diablo31170 Messages postés 17 Date d'inscription mercredi 15 mai 2013 Statut Membre Dernière intervention 13 juin 2006
10 mai 2006 à 18:54
Merci pour vos réponse mais j'ai un doute : je doit mettre le code de l'emetteur (client) et du recpeteur (serveur) dans un même fichier.cpp ou dans deux fichiers séparés ?

Une autre question pour toi AlexN : j ai pas compris ou il faut meetre ce bout de code :

myinet.h :
#define MYCORPS 16struct mymsg{
uint32_t entete;
char corps[MYCORPS];
};

#define BACKLOG 64

Merci de vos reponses futures et à bientôt
0
zytry Messages postés 12 Date d'inscription mardi 7 janvier 2003 Statut Membre Dernière intervention 12 septembre 2006
10 mai 2006 à 20:21
Tu dois avoir 3 fichiers : 2 .cpp et un myinet.h dans le meme repertoire.
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
10 mai 2006 à 22:05
Oui,

puis compilation :

cc emetteur.c -o e
cc recepteur.c -o r

Pour tester en local,
Lancer le recepteur en arrière plan (ici port 2) :
r 2 &
Lancer l'emetteur :
e localhost 2
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
11 mai 2006 à 09:09
Salut, si ca peut t'aider, va jeter un oeuil sur une de mes sources
http://www.cppfrance.com/codes/ECHANGE-FICHIER-AVEC-SERVEUR-MULTICLIENT_30629.aspx

TuRn3r
0
diablo31170 Messages postés 17 Date d'inscription mercredi 15 mai 2013 Statut Membre Dernière intervention 13 juin 2006
11 mai 2006 à 12:49
Merci pour vos programmes, cela marche a merveille mais j'ai encore un tout petit souci :

je lance au plan arriere le recepteur, puis je lance l emetteur, donc le recepteur marque

cpt_serveur 96 : message 88 - Pour voir, ainsi de suite...



Cela veut dire quoi ?

Si je marque un message dans la console de l'emtteur, cela vas apparaitre ou ?



Merci encore une fois et merci de vos réponses futures



PS : il fallait dire que les programmes marche qu'en super utilisateur ^^
0
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
11 mai 2006 à 13:04
Il faut pas que tu lance le recepteur en arriere plan (avec un &) car tu peux plus avoir acces à la console.
Lance 2 consoles. Une avec l'emetteur et une avec le recepteur.

TuRn3r
0
diablo31170 Messages postés 17 Date d'inscription mercredi 15 mai 2013 Statut Membre Dernière intervention 13 juin 2006
11 mai 2006 à 15:28
Salut a tous,



Ala place du While(++cpt) dans l'emetteur.c, j'ai remplacé ce bout de
code : il permet a l'utilisateur de taper une trame(chaine de
caractère) et donc d'afficher cette trame dans la console du recpeteur,
mais j'ai un probleme avec le scanf.



char * a;



<meta http-equiv= "Content-Type" content="text/html; charset=UTF-8">
<meta name="Generator" content="Kate, the KDE Advanced Text Editor">

printf("Taper votre trame \n");

scanf("%c",&a);

printf("%c \n",a);

strcpy (msg.corps, a);
ret_send = send(sockfd, &msg, sizeof (msg), 0);
if (ret_send == -1) { perror ("send()\n"); exit(EXIT_FAILURE); }
sleep(1);


En fait, ce que j'ai envie de faire c'est d'envoyer une trame au recepteur et de l'afficher.



Merci de vos réponses et a bientot
0
cs_AlexN Messages postés 694 Date d'inscription lundi 5 décembre 2005 Statut Membre Dernière intervention 8 janvier 2014 19
11 mai 2006 à 15:49
char *a;
scanf (..., &a);

Tu donnes a scanf l'adresse d'un pointeur sur char pas d'un char.

char a;
scanf(...,&a);
strcpy (msg.corps, &a)

Si tu disposes d'un shell avec job control, tu pourras également faire basculer les tâches depuis une unique console.
0
diablo31170 Messages postés 17 Date d'inscription mercredi 15 mai 2013 Statut Membre Dernière intervention 13 juin 2006
11 mai 2006 à 19:41
Merci pour ta réponse, j'ai essayer avec une nouvelle méthode :



#include <string.h>



string a = " ";

fprintf("Taper votre trame \n");

scanf("%s",a)

strcpy(msg.corps, &a);



Mon but est d'arriver à taper une trame (c'est une chaine de caractères avec des chiffres et des nombres), et ensuite que cette

trame soit envoyé et afficher par le récepteur.

J'ai essayer de le faire avec un string, mais en C, le compilateur connait le string ?

Quelles sont les erreurs dans mon petit bout de programme car il ne reconnait pas string ?



Merci de vos réponse futures et @ bientôt.
0
Rejoignez-nous