IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

probleme avec les socket (comportement bizarre)


Sujet :

Réseau C

  1. #1
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut probleme avec les socket (comportement bizarre)
    voila mes code server et client :

    server.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>  
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
     
     
     
     
    int main(int argc,char **argv){
     
     
    	int  id, id_clt;
    	char message[20] ;
    	char *nickname ;
    	struct sockaddr_in my_addr;		
    	struct sockaddr_in clt_addr;
     
     
     
     
     
     
     
    	id = socket(AF_INET, SOCK_STREAM , 0);
     
     
    	my_addr.sin_family 	  = AF_INET;
    	my_addr.sin_port   	  = htons(atoi(argv[1]));
    	my_addr.sin_addr.s_addr   = htonl(INADDR_ANY); 
     
    	if( bind(id, (struct sockaddr *) &my_addr,sizeof(my_addr)) < 0 ){
    		printf("bind() ERROR\n");
    		exit(0);
    	}
     
    	if( listen(id, 5) < 0 )
    		printf("listen() ERROR\n");
     
    	int taille = sizeof(clt_addr);
     
     
     
     
    	if( (id_clt = accept(id, (struct sockaddr*)&clt_addr, &taille)) < 0) 
    		printf ("accept() ERROR\n");
     
    	printf("Machine %s Connected !\n",(char *)inet_ntoa(clt_addr.sin_addr));
     
     
     
    	if( recv(id_clt, nickname, 100, 0) == -1){
    		printf("recv ERROR\n");
    		exit(0);
    	}
     
     
     
    }
    client.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>  
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
     
    int main(int argc,char **argv){
     
    	int id ;
    	struct sockaddr_in my_addr;
    	struct in_addr ip ;
    	char message[100] ,nickname[100] ;
     
     
     
           	inet_aton("127.0.0.1", &ip);
     
     
    	id = socket(AF_INET, SOCK_STREAM , 0);
     
     
    	       int inet_aton(const char *cp, struct in_addr *inp);
     
     
    	my_addr.sin_family 	  = AF_INET	;
    	my_addr.sin_port   	  = htons(atoi(argv[1]));
    	my_addr.sin_addr   	  = ip		; 
     
    	if( connect(id, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0 ){
    		printf("connect() ERROR\n");
    		exit(0);
    	}
     
    	printf("Saisir votre nickname : ");
    	gets(nickname);
    	send(id, nickname, strlen(nickname), 0) ;
     
     
     
    }
    et voila l'execution !!!
    un comportement bizzard !!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Saisir votre nickname : yous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Machine 127.0.0.1 Connected !
    recv ERROR

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Remplace tous tes printf ("xxxx() ERROR"); par perror ("xxxx() ERROR"); si tu veux avoir le message correspond à l'erreur qui s'est produite.

  3. #3
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    j'ai eu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    recv ERROR
    : Bad address

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Dans ton serveur, nickame n'est pas un tableau mais un pointeur « char * ». Moralité, tout ce que tu vas y déposer va écraser ce qui se trouve à côté. Essaie déjà de corriger ce point.

  5. #5
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    oui c'était effectivement le problème. merci bcp
    donc dans mes programmes future je dois jamais utiliser un char * ?

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Ce n'est pas que tu ne dois « jamais ». Dans certains cas, ce sera tout-à-fait approprié. Mais il faut être sûr d'avoir compris comment ça fonctionne.

    « char * » est un pointeur vers un caractère (et éventuellement ceux qui le suivent, donc, ce qui permet d'implémenter les chaînes). Un pointeur « char * » alloue donc suffisamment de mémoire pour contenir une adresse mémoire, soit 4 octets, mais pas les données qu'elle est censée pointer.

  7. #7
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    merci bcp mais j'ai un autre problème
    ce bout de code au-dessous marche tres bien sous linux mais sur windows ça bloque chez le recv() sachant que j'envoi rien du tout et que la partie ou se trouve recv() ne doit être declanché que si quelque chose arrive grâce a la fonction select()
    est ce que select() beug sur windows ou quoi ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    	FD_ZERO(&rfds);
     
     
     
    	while(1){
     
    		FD_SET(0, &rfds);
    		FD_SET(id, &rfds);	
     
    		retval = select(id+1, &rfds, NULL, NULL, NULL);
     
    		if( FD_ISSET(id, &rfds) ){
     
    			if( (n = recv(id, message, 100, 0)) == -1)
    				erreur("recv() erreur : ");
    			//
     
    		}
    		else if( FD_ISSET(0, &rfds) ){
    			//
    		}
     
     
    	}

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Citation Envoyé par yous18 Voir le message
    est ce que select() beug sur windows ou quoi ?
    Probablement pas, mais select() peut effectivement sortir en l'absence de descripteurs signalés, dans certaines conditions : soit le délai de grâce est écoulé (donc, timeout, mais cela ne te concerne pas ici car le pointeur concerné est NULL), soit sur réception d'un signal, au moins sous UNIX.

    Il se peut aussi que le socket en question soit mort ou refermé, principalement parce que le client de l'autre côté, s'est terminé.

    La page MSDN de select() est ici : http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Il y est écrit :

    Return Value

    The select function returns the total number of socket handles that are ready and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.

    Il faut donc que tu vérifies d'abord si « retval » vaut 0 ou SOCK_ERROR avant d'entreprendre la vérification de tes sockets.

  9. #9
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    effectivement il y a une erreur avec le select car elle retourne -1 avec un code erreur 10038 quel est ce problème ?

  10. #10
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    il disent dans la doc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    WSAENOTSOCK
    10038
     
     
     
    Socket operation on nonsocket.
     
        An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
    mais j'utilise bien un descripteur de socket !!
    une autre chose est ce normal que windows donne le même descripteur au client et au serveur (80 dans mon cas) ?

  11. #11
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    j'ai trouvé l'erreur : c'est que le descripteur de stdin en windows ne correspond pas à 0.
    donc quel est sa valeur ?

  12. #12
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Malheureusement, c'est beaucoup plus pénible : la version Windows de select() ne fonctionne que pour les sockets

    On en parlait déjà ici : http://www.developpez.net/forums/d13...nction-select/

  13. #13
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    j'ai utilisé les threads sous windows et ça marche au lieu de select.
    2 threads un pour traiter le recv() de la socket et un autre pour la saisie des donné (stdin)

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 373
    Points : 23 629
    Points
    23 629
    Par défaut
    Oui, ben c'est pas une habitude à prendre ! select() est justement censé éviter ça. Bon, en l'occurence ça ne marche pas, mais il y a d'autres appels systèmes sous Windows pour faire cela.

    Trois threads pour gérer un socket et lire l'entrée standard, ça commence à coûter cher.

  15. #15
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    mais qu'elles sont les autres alternatifs de select pour stdin sur windows ?
    de quel appel système vous parlez ?

Discussions similaires

  1. probleme avec les sockets
    Par yous18 dans le forum Réseau
    Réponses: 3
    Dernier message: 10/04/2010, 12h09
  2. problem avec les sockets
    Par nadiamo dans le forum C++Builder
    Réponses: 4
    Dernier message: 01/06/2009, 20h08
  3. probleme avec les sockets
    Par younesgates dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 23/01/2009, 21h50
  4. probleme avec les sockets
    Par lilou77 dans le forum C++
    Réponses: 2
    Dernier message: 27/08/2007, 14h54
  5. probleme avec les sockets
    Par iznogoud36 dans le forum Linux
    Réponses: 4
    Dernier message: 20/12/2006, 10h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo