[winsock] Client/Server simplifié....

Client/Server simplifié.... [winsock] - C - Programmation

Marsh Posté le 27-08-2006 à 13:07:17    

Salut tout le monde.
Tout d’abor je tien a préciser que je suis débutant avec l’utilisation des sockets en langage C, alors ne soyez pas surpris si ma question parés bette !  LoOoL.
 
J’ai essayé de faire un petit programme Client/serveur très très simplifié, dont voilà le code :
 
Client :

Code :
  1. // client simple
  2. #include <winsock2.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <windows.h>
  7. char bufferRecv[800];
  8. char bufferSend[800];
  9. int res;
  10. char ip[16];
  11. int port;
  12. int main(void)
  13. {
  14.         puts(" <<<-=[ Client ]=->>>\n\n" );
  15.         WSADATA WSAData;
  16.         WSAStartup(MAKEWORD(2,0), &WSAData);
  17.         printf("%s","IP : " );
  18.         fgets(ip,sizeof(ip),stdin);
  19.         printf("%s","PORT : " );
  20.         scanf("%d",&port);
  21.         SOCKET sock;
  22.         SOCKADDR_IN sin;
  23.         sock = socket(AF_INET, SOCK_STREAM, 0);
  24.         sin.sin_addr.s_addr    = inet_addr(ip);
  25.         sin.sin_family    = AF_INET;
  26.         sin.sin_port    = htons(port);
  27.         if( connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != 0 )
  28.         {
  29.             puts("\n  ----------> Imposible de se connecter au server..." );
  30.             getchar();
  31.         }
  32.         do
  33.         {
  34.             fgets(bufferSend, sizeof bufferSend, stdin);
  35.             res = send(sock, bufferSend, strlen(bufferSend), 0);
  36.         }
  37.         while (res != SOCKET_ERROR);
  38.         if(res == SOCKET_ERROR)
  39.         {
  40.             puts("\n  ----------> SOCKET_ERROR : Impossible d'envoyer au server..." );
  41.             getchar();
  42.         }
  43.     return 0;
  44. }


 
Server :

Code :
  1. // serveur simple
  2. #include <winsock2.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <windows.h>
  7. char bufferRecv[800];
  8. char bufferSend[800];
  9. int rec;
  10. #define PORT 1000
  11. int main(void)
  12. {
  13. printf("%s"," -=[ Serveur ]=-\n\n" );
  14.         WSADATA WSAData;
  15.         WSAStartup(MAKEWORD(2,0), &WSAData);
  16.         SOCKET sock;
  17.         SOCKET csock;
  18.         SOCKADDR_IN sin;
  19.         SOCKADDR_IN csin;
  20.         sock = socket(AF_INET, SOCK_STREAM, 0);
  21.         sin.sin_addr.s_addr    = INADDR_ANY;
  22.         sin.sin_family    = AF_INET;
  23.         sin.sin_port    = htons(PORT);
  24.         bind(sock, (SOCKADDR *)&sin, sizeof(sin));
  25.         listen(sock, 3);
  26.         int sizeofcsin = sizeof(csin);
  27.         csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);
  28.         while (1)
  29.         {
  30.                 rec = recv (csock, bufferRecv, sizeof(bufferRecv), 0);
  31.                   bufferRecv[rec] = '\0';
  32.                   puts(bufferRecv);
  33.                   MessageBox(0,bufferRecv,"salut",MB_OK | MB_ICONERROR);
  34.         }
  35.     return 0;
  36. }


 
Le problème c’est que quand le client envoi un message au server ca marche il l’affiche, mais dés que je ferme le client le server affiche le dernier message envoyé sans arrêt càd un boucle infini !
Et je ne vois pas où le problème peut-il bien être !
 
Merci pour votre aide.
A bien tôt. :)

Message cité 1 fois
Message édité par Bad_Day le 28-08-2006 à 13:47:54
Reply

Marsh Posté le 27-08-2006 à 13:07:17   

Reply

Marsh Posté le 27-08-2006 à 13:12:13    

Salut
Je croi que ta oublier de liberer ta socket:

Code :
  1. close(sock);
  2. WSACleanup();


 
à la fin , essay ca peut toujours servir  :)  
 
 

Reply

Marsh Posté le 27-08-2006 à 13:29:39    

big_dadi_fat a écrit :

Salut
Je croi que ta oublier de liberer ta socket:

Code :
  1. close(sock);
  2. WSACleanup();


 
à la fin , essay ca peut toujours servir  :)


 
j'ai ajouter close(sock)  et   WSACleanup()     mais c'été pas ca qui créai le problème  :(
 

Reply

Marsh Posté le 27-08-2006 à 13:33:42    

Bad_Day a écrit :

J’ai essayé de faire un petit programme Client/serveur très très simplifié, dont voilà le code :
<...>
Le problème c’est que quand le client envoi un message au server ca marche il l’affiche, mais dés que je ferme le client le server affiche le dernier message envoyé sans arrêt càd un boucle infini !
Et je ne vois pas où le problème peut-il bien être !


Déjà, es-tu bien conscient que fgets() prend le '\n' ? Pour l'IP, ça va pas le faire...
 
Ensuite, tu utilises strlen() à l'emission, donc tu ne transmets pas le 0. Normal.
 
Par contre, en réception, il faut utiliser le nombre de caractères reçus (renvoyé par recv()) pour placer le 0 au bon endroit... OK, mais il faut laisser une place pour le 0 :  

Code :
  1. rec = recv (csock, bufferRecv, sizeof bufferRecv - 1, 0);


 
http://mapage.noos.fr/emdel/reseaux.htm
 
Pour le problème de boucle, il faut tester la valeur retournée par recv(). En cas de deconnexion, c'est -1...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 27-08-2006 à 13:35:34

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-08-2006 à 13:51:05    

Emmanuel Delahaye a écrit :

Déjà, es-tu bien conscient que fgets() prend le '\n' ? Pour l'IP, ça va pas le faire...
 
Ensuite, tu utilises strlen() à l'emission, donc tu ne transmets pas le 0. Normal.
 
Par contre, en réception, il faut utiliser le nombre de caractères reçus (renvoyé par recv()) pour placer le 0 au bon endroit... OK, mais il faut laisser une place pour le 0 :  

Code :
  1. rec = recv (csock, bufferRecv, sizeof bufferRecv - 1, 0);


 
http://mapage.noos.fr/emdel/reseaux.htm
 
Pour le problème de boucle, il faut tester la valeur retournée par recv(). En cas de deconnexion, c'est -1...


 
EDIT: je chérchais depuis un moment un site en francais qui explique bien les socket avec des exemple etc .. et le lien http://mapage.noos.fr/emdel/reseaux.html me plais , je ne vois pas comment je ne l'ai pas trouvé avant, LoOoL .
 
 
merci Emmanue, je vais essayé de corrigé tout ça  :)  
 
il y a encors un autre probléme :
quand je saisi le numéro de port et valide par ok y a un message vide qui est envoyé au server ! c'est à cause du scanf ?  :heink:
 
 

Message cité 1 fois
Message édité par Bad_Day le 27-08-2006 à 13:56:56
Reply

Marsh Posté le 27-08-2006 à 14:13:24    

Bad_Day a écrit :

quand je saisi le numéro de port et valide par ok y a un message vide qui est envoyé au server ! c'est à cause du scanf ?  :heink:


Possible qu'il y ait un '\n' qui traine. Je n'utilise pas scanf()... Trop compliqué.
 
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers
 
Il vaut mieux maîtriser le C avant de se lancer dans les chaussettes...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-08-2006 à 14:19:40    

Emmanuel Delahaye a écrit :

Possible qu'il y ait un '\n' qui traine. Je n'utilise pas scanf()... Trop compliqué.
 
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers


Oui c'est vrai que l'utilisation du scanf est souvant dangeureuse. J'ai lu un tuto sur la bonne utilisation de scanf sur developpez (je ne me rappel plu du lien) mais c'est un peut chaud d'utiliser scanf correctement lol.
 

Citation :

Il vaut mieux maîtriser le C avant de se lancer dans les chaussettes


LoOoL  :lol:  
 
 

Reply

Marsh Posté le 27-08-2006 à 14:34:54    

Encor un petit problème . svp:
J'ai commencé avec les socket il n y a qu'un jours  :(  donc je débute  :p  :   et
Je ne comprend pas bien le fonctionement de la fonction accept:
càd:
quand je fais

Code :
  1. int sizeofcsin = sizeof(csin);
  2. csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);


ca marche. Mais si je fais directement:

Code :
  1. csock = accept(sock, (SOCKADDR *)&csin, sizeof(csin));


il me met un warning (genr: invalid type convertion (cast)), et au début de l'execution il y a une boucle infini de message. (meme si je cast).
donc je ne comprend pas differance entre les 2 code .
 :jap:  
 

Reply

Marsh Posté le 27-08-2006 à 15:00:14    

Bad_Day a écrit :

Je ne comprend pas bien le fonctionement de la fonction accept:
càd:
quand je fais

Code :
  1. int sizeofcsin = sizeof(csin);
  2. csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);


ca marche. Mais si je fais directement:

Code :
  1. csock = accept(sock, (SOCKADDR *)&csin, sizeof(csin));


il me met un warning (genr: invalid type convertion (cast)), et au début de l'execution il y a une boucle infini de message. (meme si je cast).
donc je ne comprend pas differance entre les 2 code .


C'est un problème de C. Si une fonction attend l'adresse d'une variable, il ne faut pas lui donner autre chose, sinon, le comportement est indéfini...
 
Une taille, c'est pas l'adresse d'une variable...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-08-2006 à 15:14:32    

Emmanuel Delahaye a écrit :

C'est un problème de C. Si une fonction attend l'adresse d'une variable, il ne faut pas lui donner autre chose, sinon, le comportement est indéfini...
Une taille, c'est pas l'adresse d'une variable...


 
ah ok, donc la fonction accept() à comme 3eme parametre un pointeur sur la variable qui contien la taille de notre structure . Je pensais que c'été la taille de la structure qu'elle prend.  
ok et bien merci pour votre aide et pour les liens que vous m'avais donnez.  :hello:  
 
 
 :)

Reply

Marsh Posté le 27-08-2006 à 15:14:32   

Reply

Marsh Posté le 28-08-2006 à 13:58:32    

Re-salut  :hello:  
J'ai un peut lu les exemple de client server qu'il y a sur le site http://mapage.noos.fr/emdel/reseaux.htm que vous m'avez donné, mais j'ai un petit problème à comprendre des petit truc dans ces code:
 
par exemple:
 

Code :
  1. sock_err = closesocket (sock), sock = INVALID_SOCKET;


moi j'ai toujours utilisé: close(sock); tout court lol, et je ne comprend pas ce code là  :( .
 
et aussi:

Code :
  1. perror ("socket.open" );
  2. perror ("socket.close" );


à quoi ca sert ca   :??: .
 
Je suis vraiment désolé si se sont des questions bettes  :p . mais SVP expliquez moi.
Merci Emmanuel.

Message cité 1 fois
Message édité par Bad_Day le 28-08-2006 à 14:00:42
Reply

Marsh Posté le 28-08-2006 à 14:09:01    

Bad_Day a écrit :


Code :
  1. sock_err = closesocket (sock), sock = INVALID_SOCKET;


moi j'ai toujours utilisé: close(sock); tout court lol, et je ne comprend pas ce code là  :( .


close() n'existe pas sous Windows. C'est closesocket().  
 
Sous unixoide, on met soit close(), soit closesocket() avec un define.

Code :
  1. #define closesocket(s) close(s)


J'ai fourni un fichier d'entête qui permet la compatibilité unix/windows...

Citation :


et aussi:

Code :
  1. perror ("socket.open" );
  2. perror ("socket.close" );


à quoi ca sert ca   :??: .


perror() est une fonction standard du C.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-08-2006 à 14:21:43    

ok, donc j'utilise closesocket (sock); .Mais je vois que vous mettez un virgule aprés et sock = INVALID_SOCKET;
 

Code :
  1. sock_err = closesocket (sock), sock = INVALID_SOCKET;


j'ai jamais vu ca avant lol, a quoi ca sert ?  
 
 

Citation :

perror() est une fonction standard du C


Ok , mais j'ai trouvé http://www.linux-kheops.com/doc/ma [...] ror.3.html qu'on dois passé une chaine de caractére a cette fonction, or je ne comprend pas bien la singification de "socket.open" et "socket.close"  :(  , esque ce sont les chaine de caractére que La fonction perror() affiche sur la sortie d'erreur standard ?
 
 

Reply

Marsh Posté le 28-08-2006 à 15:41:28    

Bad_Day a écrit :

ok, donc j'utilise closesocket (sock); .Mais je vois que vous mettez un virgule aprés et sock = INVALID_SOCKET;
 

Code :
  1. sock_err = closesocket (sock), sock = INVALID_SOCKET;


j'ai jamais vu ca avant lol, a quoi ca sert ?  


Comme on a fermé le socket, sa valeur n'est plus valide. Je le force donc à une valeur explicitement invalide (ça bugge plus vite et de manière certaine en cas de réutilisation abusive). Ca permet de le tester. Comme avec un pointeur et NULL...
 
Ici, l'opérateur ',' n'a pas de rôle fonctionnel particulier, si ce n'est qu'il prétend montrer à l'utilisateur du code que la séquence de code doit être respectée. (Ne rien mettre entre les deux instructions).

Citation :


Citation :

perror() est une fonction standard du C


Ok , mais j'ai trouvé http://www.linux-kheops.com/doc/ma [...] ror.3.html Oui, cu'on dois passé une chaine de caractére a cette fonction, or je ne comprend pas bien la singification de "socket.open" et "socket.close"  :(  , esque ce sont les chaine de caractére que La fonction perror() affiche sur la sortie d'erreur standard ?


La chaine de caractère n'a qu'un rôle documentaire. Elle permet de savoir de quoi on parle.
 
Comme indiqué dans la doc, la chaine et le message d'erreur sont sortis sur la sortie erreur (stderr).


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-08-2006 à 15:57:26    

Ok merci pour votre explication, je vais me remetre au code qu'il y a sur ton site  :) .
j'ai aussi trouvé ce tuto en francais il est complais (mais c'est pour unix  :(  ) , enfin bref http://vidalcharles.free.fr/lf/socket.html
 
encor merci  :)  
 
 
 :hello:

Reply

Marsh Posté le 28-08-2006 à 16:57:49    

Bad_Day a écrit :

j'ai aussi trouvé ce tuto en francais il est complaiset (mais c'est pour unix  :(  ) , enfin bref http://vidalcharles.free.fr/lf/socket.html


J'ai pas tout lu en détail, mais le gars est mûr pour écrire un tuto pour le Site du Zéro !
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 30-08-2006 à 13:46:20    

Re  :)  
J'ai un peut amélioré le petit code du server en suivant un peut l'exemple sur ton site:

Code :
  1. // serveur simple
  2. #include <winsock2.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define PORT 1000
  6. int main(void)
  7. {
  8.     char bufferRecv[800];
  9.     char bufferSend[800];
  10.     int error;
  11.     printf("<[ Serveur ]>\n\n" );
  12.     WSADATA WSAData;
  13.     WSAStartup(MAKEWORD(2,0), &WSAData);
  14.     SOCKADDR_IN sin = {0};
  15.     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
  16.     if( sock != INVALID_SOCKET )
  17.     {
  18.         printf(":-) Socket %d is now opened in TCP/IP mode.\n",sock);
  19.         sin.sin_addr.s_addr    = htonl(INADDR_ANY);
  20.         sin.sin_family    = AF_INET;
  21.         sin.sin_port    = htons(PORT);
  22.         error = bind(sock, (SOCKADDR *)&sin, sizeof(sin));
  23.         if( error != SOCKET_ERROR )
  24.         {
  25.             error = listen(sock, 2);
  26.             if( error != SOCKET_ERROR )
  27.             {
  28.                 printf(":-) listening on port %d\n"
  29.                        "Waiting for a client connection on this port...\n",PORT);
  30.                 SOCKADDR_IN csin = {0};
  31.                 int sizeofcsin = sizeof(csin);
  32.                 SOCKET csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);
  33.                 if( csock != INVALID_SOCKET )
  34.                 {
  35.                     printf(":::: Client connected withe socket %d, from %s: %d",
  36.                             csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
  37.                     int go = 1;
  38.                     while(go)
  39.                     {
  40.                         error = recv (csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  41.                         if(error != SOCKET_ERROR)
  42.                         {
  43.                             int PourTester=sizeof(bufferRecv)-1;
  44.                             bufferRecv[error] = '\0';
  45.                             printf("\n PourTester = %d \n error = %d",PourTester,error);
  46.                             puts(bufferRecv);
  47.                             if( strcmp(bufferRecv,"exit" ) == 0 )   go = 0;
  48.                         }
  49.                         else
  50.                         {
  51.                             printf(":-/ Socket error, recev !\n" );
  52.                             go = 0;
  53.                         }
  54.                     }
  55.                     shutdown(csock, 2);
  56.                     closesocket(csock);
  57.                     printf(":::: Client socket %d is now closed.\n",csock);
  58.                 }
  59.                 else
  60.                 {
  61.                     printf(":-/ Invalide Socket, error in opening Client socket\n" );
  62.                     system("pause" );
  63.                     return EXIT_FAILURE;
  64.                 }
  65.             }
  66.         }
  67.         closesocket(sock);
  68.         printf(":::: Server socket %d is now closed.\n",sock);
  69.     }
  70.     else
  71.     {
  72.         printf(":-/ Invalide Socket, erreur in opening Server socket\n" );
  73.         system("pause" );
  74.         return EXIT_FAILURE;
  75.     }
  76.     WSACleanup();
  77.     system("pause" );
  78.     return EXIT_SUCCESS;
  79. }


 
mais il y a des truc que je ne comprend pas vraiment bien, comme par exemple :
 
la fonction inet_ntoa(csin.sin_addr); (networck to acci) que vous utilisez pour identifier le client qui se connecte au server.
et htons(csin.sin_port); c'est pour idantifier le port ? je croyais que c'été le port 1000 (dans cette exemple)  !  ou alors un autre port   :??:  
 
et j'ai aussi un autre probléme dans ce bout de code:

Code :
  1. while(go)
  2.                     {
  3.                         error = recv (csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  4.                         if(error != SOCKET_ERROR)
  5.                         {
  6.                             int PourTester=sizeof(bufferRecv)-1;
  7.                             bufferRecv[error] = '\0';
  8.                             printf("\n PourTester = %d \n error = %d",PourTester,error);
  9.                             puts(bufferRecv);
  10.                             if( strcmp(bufferRecv,"exit" ) == 0 )   go = 0;
  11.                         }
  12.                         else
  13.                         {
  14.                             printf(":-/ Socket error, recev !\n" );
  15.                             go = 0;
  16.                         }
  17.                     }


J'ai essayais d'afficher le sizeof(bufferRecv) et la valeur retourné par la fonction recv() , mais il me donne des résultat spectaculére  :heink: .
 
je ne vois pas ou est le probléme.. snif
 
 :)

Message cité 1 fois
Message édité par Bad_Day le 30-08-2006 à 13:46:52
Reply

Marsh Posté le 30-08-2006 à 18:12:37    

Bad_Day a écrit :


mais il y a des truc que je ne comprend pas vraiment bien, comme par exemple :
 
la fonction inet_ntoa(csin.sin_addr); (networck to acci) que vous utilisez pour identifier le client qui se connecte au server.


cette fonction transforme l'adresse IP du client en une chaine imprimable.


<[ Serveur ]>
 
:-) Socket 1956 is now opened in TCP/IP mode.
:-) listening on port 1000
Waiting for a client connection on this port...
:::: Client connected withe socket 1928, from 127.0.0.1: 4813


Apparement, ça fonctionne pas mal...

Citation :


et htons(csin.sin_port); c'est pour idantifier le port ? je croyais que c'été le port 1000 (dans cette exemple)  !  ou alors un autre port   :??:  


Ben oui, c'est le port du cient. Il est attribué automatiquement pas le système du client.

Citation :


et j'ai aussi un autre probléme dans ce bout de code:

Code :
  1. while(go)
  2.                     {
  3.                         error = recv (csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  4.                         if(error != SOCKET_ERROR)
  5.                         {
  6.                             int PourTester=sizeof(bufferRecv)-1;
  7.                             bufferRecv[error] = '\0';
  8.                             printf("\n PourTester = %d \n error = %d",PourTester,error);
  9.                             puts(bufferRecv);
  10.                             if( strcmp(bufferRecv,"exit" ) == 0 )   go = 0;
  11.                         }
  12.                         else
  13.                         {
  14.                             printf(":-/ Socket error, recev !\n" );
  15.                             go = 0;
  16.                         }
  17.                     }


J'ai essayais d'afficher le sizeof(bufferRecv) et la valeur retourné par la fonction recv() , mais il me donne des résultat spectaculére  :heink: .

Moi, avec ton code, je vois 799...

<[ Serveur ]>
 
:-) Socket 1956 is now opened in TCP/IP mode.
:-) listening on port 1000
Waiting for a client connection on this port...
:::: Client connected withe socket 1928, from 127.0.0.1: 4813
 PourTester = 799
 error = 1a


soit 800 - 1. Rien de spéctaculaire.
Ensuite, je vois 1 (j'ai tapé 'a', soit 1 caractère) et le 'a' que j'ai tapé sur le client Telnet.
 
Rien que de très normal.
 
Par contre, avec un client Telnet (terminal caractères), la caractères arrivent un par un. C'est à toi de les assembler (le \n ou \r est la fin de commande) pour constituer une commande complète et valide. Ajouer le 0 final.


Message édité par Emmanuel Delahaye le 31-08-2006 à 14:56:31

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-08-2006 à 14:42:13    

RE...  :hello:  
 
J'ai essayer de faire communiquer le client et le serveur (echanger des msg entre les 2 parties).
Voilà le code:
 
serveur:

Code :
  1. // serveur simple
  2. #include <winsock2.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #define PORT 1000
  6. int main(void)
  7. {
  8.     char bufferRecv[800];
  9.     char bufferSend[800];
  10.     int error;
  11.     printf("<[ Serveur ]>\n\n" );
  12.     WSADATA WSAData;
  13.     WSAStartup(MAKEWORD(2,0), &WSAData);
  14.     SOCKADDR_IN sin = {0};
  15.     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
  16.     if( sock != INVALID_SOCKET )
  17.     {
  18.         printf(":-) Socket %d is now opened in TCP/IP mode.\n",sock);
  19.         sin.sin_addr.s_addr    = htonl(INADDR_ANY);
  20.         sin.sin_family    = AF_INET;
  21.         sin.sin_port    = htons(PORT);
  22.         error = bind(sock, (SOCKADDR *)&sin, sizeof(sin));
  23.         if( error != SOCKET_ERROR )
  24.         {
  25.             error = listen(sock, 2);
  26.             if( error != SOCKET_ERROR )
  27.             {
  28.                 printf(":-) listening on port %d\n"
  29.                        "Waiting for a client connection on this port...\n",PORT);
  30.                 SOCKADDR_IN csin = {0};
  31.                 int sizeofcsin = sizeof(csin);
  32.                 SOCKET csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);
  33.                 if( csock != INVALID_SOCKET )
  34.                 {
  35.                     printf("::::: Client connected withe socket %d, from %s: %d\n\n",
  36.                             csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
  37.                     int go = 1;
  38.                     while(go)
  39.                     {
  40.                         error = recv(csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  41.                         if(error != SOCKET_ERROR)
  42.                         {
  43.                             bufferRecv[error] = '\0';
  44.                             printf("    CLIEN DIT: %s\n",bufferRecv);
  45.                         }
  46.                         else
  47.                         {
  48.                             printf(":-/ Socket error, recv !\n" );
  49.                             go = 0;
  50.                         }
  51.                         char bufferSend[50];
  52.                         printf("    SERVER DIT: " );
  53.                         fgets(bufferSend, sizeof(bufferSend), stdin);
  54.                         error = send(csock, bufferSend, sizeof(bufferSend), 0);
  55.                         if(error == SOCKET_ERROR)
  56.                         {
  57.                             printf(":-/ Socket error, send !\n" );
  58.                             go = 0;
  59.                         }
  60.                     }
  61.                     shutdown(csock, 2);
  62.                     closesocket(csock);
  63.                     printf("::::: Client socket %d is now closed.\n",csock);
  64.                 }
  65.                 else
  66.                 {
  67.                     printf(":-/ Invalide Socket, error in opening Client socket\n" );
  68.                     system("pause" );
  69.                     return EXIT_FAILURE;
  70.                 }
  71.             }
  72.         }
  73.         closesocket(sock);
  74.         printf(":::: Server socket %d is now closed.\n",sock);
  75.     }
  76.     else
  77.     {
  78.         printf(":-/ Invalide Socket, erreur in opening Server socket\n" );
  79.         system("pause" );
  80.         return EXIT_FAILURE;
  81.     }
  82.     WSACleanup();
  83.     system("pause" );
  84.     return EXIT_SUCCESS;
  85. }


 
client:

Code :
  1. // client simple
  2. #include <winsock2.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define IP "127.0.0.1"
  7. #define PORT 1000
  8. int main(void)
  9. {
  10.     int error;
  11.     puts(" <[ Client ]>\n\n" );
  12.     WSADATA WSAData;
  13.     WSAStartup(MAKEWORD(2,0), &WSAData);
  14.     SOCKET sock = sock = socket(AF_INET, SOCK_STREAM, 0);
  15.     if( sock != INVALID_SOCKET )
  16.     {
  17.         printf(":-) Socket %d is new opened in TCP/IP mode.\n",sock);
  18.         SOCKADDR_IN sin;
  19.         sin.sin_addr.s_addr    = inet_addr(IP);
  20.         sin.sin_family    = AF_INET;
  21.         sin.sin_port    = htons(PORT);
  22.         error = connect(sock, (SOCKADDR *)&sin, sizeof sin);
  23.         if( error != SOCKET_ERROR )
  24.         {
  25.             char bufferSend[50];
  26.             char bufferRecv[50];
  27.             int go = 1;
  28.             printf(":-) Connected to server...\n\n" );
  29.             do
  30.             {
  31.                 printf("    CLIENT DIT: " );
  32.                 fgets(bufferSend, sizeof bufferSend, stdin);
  33.                 error = send(sock, bufferSend, sizeof(bufferSend), 0);
  34.                 if(error == SOCKET_ERROR)   go = 0;
  35.                 error = recv(sock, bufferRecv, sizeof(bufferRecv)-1, 0);
  36.                 if(error == SOCKET_ERROR)   go = 0;
  37.                 else
  38.                 {
  39.                     bufferRecv[error] = '\0';
  40.                     printf("    SERVER DIT: %s.\n",bufferRecv);
  41.                 }
  42.             }
  43.             while (go);
  44.             printf("::::: send imposible, closing socket...\n" );
  45.             closesocket(sock);
  46.             printf("::::: Socket %d is new closed.\n",sock);
  47.         }
  48.         else
  49.         {
  50.             printf(":-/ Not connected ! connection failure.\n" );
  51.             return EXIT_FAILURE;
  52.         }
  53.     }
  54.     else
  55.     {
  56.         printf(":-/ Invalid Socket. Socket is not opened.\n" );
  57.         return EXIT_FAILURE;
  58.     }
  59.     WSACleanup();
  60.     system("pause" );
  61.     return EXIT_SUCCESS;
  62. }


 
 
Mais le problème cette fois c'est qu'au début ca marche mais à un sertein moment y a un décalage de message (et fais n'importe quoi) .
Je ne vois pas bien où le prob peut-il bien être .
 
 :)  

Reply

Marsh Posté le 31-08-2006 à 15:27:40    

Bad_Day a écrit :

RE...  :hello:  
 
J'ai essayer de faire communiquer le client et le serveur (echanger des msg entre les 2 parties).
Mais le problème cette fois c'est qu'au début ca marche mais à un serteincertain moment y a un décalage de message (et fais n'importe quoi) .
Je ne vois pas bien où le prob peut-il bien être .


A l'emission, du serveur, tu fais :  

Code :
  1. char bufferSend[50];
  2.                 fgets(bufferSend, sizeof bufferSend, stdin);
  3.                 error = send(sock, bufferSend, sizeof(bufferSend), 0);


Autrement dit, tu transmets systématiquement un bloc de 50 bytes, y compris le 0 final et des caractères non initialisés si la chaine utile fait moins de 48 caractères.  
 
A la reception du serveur, tu fais :  

Code :
  1. char bufferRecv[800];
  2.                         error = recv(csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  3.                         if(error != SOCKET_ERROR)
  4.                         {
  5.                             bufferRecv[error] = '\0';
  6.                             printf("    CLIEN DIT: %s\n",bufferRecv);
  7.                         }


autrement dit, tu places un 0 après les caractères reçus. C'est OK, sauf que ce qui est reçu (en fait, ce qui a été émis) est incorrect. Mais comme le 0 a été transmis, ça marchouille.
 
Il serait plus logique de ne transmettre que les caractères utiles :  

Code :
  1. error = send(sock, bufferSend, strlen(bufferSend), 0);


Je n'ai pas vérifié le sens serv -> cli.


Message édité par Emmanuel Delahaye le 31-08-2006 à 15:31:51

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 01-09-2006 à 18:28:48    

Salut
moi j'ai fait un programme pareille au tien,
il marche si je l'essay sur ma machine en local avec l'ip 127.0.0.1  .
Mais dés que je l'essay sur une autre machine avec la bonne adresse IP,
sa ne marche pas  :sweat:  
 
ce né pas un probléme de code j'ai meme essayer avec ton code là ici préson, alors je ne voi pas ou est le prob  :cry:  
 
 

Reply

Marsh Posté le 01-09-2006 à 19:25:26    

big_dadi_fat a écrit :

Salut
moi j'ai fait un programme pareille au tien,
il marche si je l'essay sur ma machine en local avec l'ip 127.0.0.1  .
Mais dés que je l'essay sur une autre machine avec la bonne adresse IP,
sa ne marche pas  :sweat:  
 
ce né pas un probléme de code j'ai meme essayer avec ton code là ici préson, alors je ne voi pas ou est le prob  :cry:


port < 1024 ? Blocage par le FireWall ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 01-09-2006 à 20:34:01    

Emmanuel Delahaye a écrit :

port < 1024 ? Blocage par le FireWall ?


J'ai essayer avec le port 1000 , comme dans l'exemple si dessu , et il n y a pas blocage par le FireWall, j'ai fait débloqué.
 
 

Reply

Marsh Posté le 01-09-2006 à 20:55:18    

big_dadi_fat a écrit :

J'ai essayer avec le port 1000 , comme dans l'exemple si dessu , et il n y a pas blocage par le FireWall, j'ai fait débloqué.


Essaye avec un port >= 1024. Sous Linux, les ports < 1024 ne sont gérables qu'en mode root. Sous Windows, c'est pas très clair...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 02-09-2006 à 17:22:42    

C'est vraie que moi aussi je n'ai jamais essayer sur un autre pc . j'ai un seul  :cry:  
 
 

Reply

Marsh Posté le 02-09-2006 à 20:05:42    

big_dadi_fat a écrit :

J'ai essayer avec le port 1000 , comme dans l'exemple si dessu , et il n y a pas blocage par le FireWall, j'ai fait débloqué.


tu devra essayer avec un port supérieur à 1024 ,
j'ai essayé avec 1000 et ca ne marchais pas comme toi , j'ai essayé avec 2000 et ca marche bien  :) .
 
 
 
 
enfait je me demande ci en peut faire en sorte que le client et le serveur peuvent envoyé des msg tout les 2 , càd en méme temp .  
j'ai essayé mais je n'arrive pas a le fair  :( . il faut toujours attendre la reponce du clien pour que le serveur puisse envoyé , et ainsi de suit ....
esqu'on peut le faire...  
 
voila les nouveau code:
 

Code :
  1. /******************************************************/
  2. /*        Client Simple                               */
  3. /*                      Par Bad_Day     ( B.M.R )     */
  4. /******************************************************/
  5. #include <winsock2.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <windows.h>
  10. #define IP "127.0.0.1"
  11. #define PORT 2000
  12. void color(int couleurDuTexte,int couleurDeFond)
  13. {
  14.         HANDLE H=GetStdHandle(STD_OUTPUT_HANDLE);
  15.         SetConsoleTextAttribute(H,couleurDeFond*16+couleurDuTexte);
  16. }
  17. int main(void)
  18. {
  19.     int error;
  20.     color(0,15);
  21.     puts(" <[ Client Bad_Day ]>\n\n" );
  22.     WSADATA WSAData;
  23.     WSAStartup(MAKEWORD(2,0), &WSAData);
  24.     SOCKET sock = sock = socket(AF_INET, SOCK_STREAM, 0);
  25.     if( sock != INVALID_SOCKET )
  26.     {
  27.         color(2,0);
  28.         printf(":-) Socket %d is new opened in TCP/IP mode.\n",sock);
  29.         SOCKADDR_IN sin;
  30.         sin.sin_addr.s_addr    = inet_addr(IP);
  31.         sin.sin_family    = AF_INET;
  32.         sin.sin_port    = htons(PORT);
  33.         error = connect(sock, (SOCKADDR *)&sin, sizeof sin);
  34.         if( error != SOCKET_ERROR )
  35.         {
  36.             char bufferSend[50];
  37.             char bufferRecv[50];
  38.             int go = 1;
  39.             color(2,0);
  40.             printf(":-) Connected to server...\n\n" );
  41.             do
  42.             {
  43.                 color(9,0);
  44.                 printf(">>>> CLIENT DIT: " );
  45.                 fgets(bufferSend, sizeof bufferSend, stdin);
  46.                 error = send(sock, bufferSend, strlen(bufferSend), 0);
  47.                 color(7,0);
  48.                 printf("\n...................Attente de la reponce du serveur (passiontez svp)....\n\n" );
  49.                 if(error == SOCKET_ERROR)   go = 0;
  50.                 error = recv(sock, bufferRecv, sizeof(bufferRecv)-1, 0);
  51.                 if(error == SOCKET_ERROR)   go = 0;
  52.                 else
  53.                 {
  54.                     bufferRecv[error] = '\0';
  55.                     color(12,0);
  56.                     printf("<<<< SERVER DIT: %s\n",bufferRecv);
  57.                 }
  58.             }
  59.             while (go);
  60.             color(1,0);
  61.             printf("::::: send imposible, closing socket...\n" );
  62.             closesocket(sock);
  63.             printf("::::: Socket %d is new closed.\n",sock);
  64.         }
  65.         else
  66.         {
  67.             color(4,0);
  68.             printf(":-/ Not connected ! connection failure.\n" );
  69.             return EXIT_FAILURE;
  70.         }
  71.     }
  72.     else
  73.     {
  74.         printf(":-/ Invalid Socket. Socket is not opened.\n" );
  75.         return EXIT_FAILURE;
  76.     }
  77.     WSACleanup();
  78.     color(7,0);
  79.     system("pause" );
  80.     return EXIT_SUCCESS;
  81. }


 
 

Code :
  1. /******************************************************/
  2. /*        Serveur Simple                              */
  3. /*                      Par Bad_Day     ( B.M.R )     */
  4. /******************************************************/
  5. #include <winsock2.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <windows.h>
  9. #define PORT 2000
  10. void color(int couleurDuTexte,int couleurDeFond)
  11. {
  12.         HANDLE H=GetStdHandle(STD_OUTPUT_HANDLE);
  13.         SetConsoleTextAttribute(H,couleurDeFond*16+couleurDuTexte);
  14. }
  15. int main(void)
  16. {
  17.     char bufferRecv[50];
  18.     int error;
  19.     color(0,15);
  20.     printf("<[ Serveur Bad_Day ]>\n\n" );
  21.     WSADATA WSAData;
  22.     WSAStartup(MAKEWORD(2,0), &WSAData);
  23.     SOCKADDR_IN sin = {0};
  24.     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
  25.     if( sock != INVALID_SOCKET )
  26.     {
  27.         color(2,0);
  28.         printf(":-) Socket %d is now opened in TCP/IP mode.\n",sock);
  29.         sin.sin_addr.s_addr    = htonl(INADDR_ANY);
  30.         sin.sin_family    = AF_INET;
  31.         sin.sin_port    = htons(PORT);
  32.         error = bind(sock, (SOCKADDR *)&sin, sizeof(sin));
  33.         if( error != SOCKET_ERROR )
  34.         {
  35.             error = listen(sock, 2);
  36.             if( error != SOCKET_ERROR )
  37.             {
  38.                 color(2,0);
  39.                 printf(":-) listening on port %d\n"
  40.                        "Waiting for a client connection on this port...\n",PORT);
  41.                 SOCKADDR_IN csin = {0};
  42.                 int sizeofcsin = sizeof(csin);
  43.                 SOCKET csock = accept(sock, (SOCKADDR *)&csin, &sizeofcsin);
  44.                 if( csock != INVALID_SOCKET )
  45.                 {
  46.                     printf("::::: Client connected\n\n" );
  47.                     int go = 1;
  48.                     while(go)
  49.                     {
  50.                         error = recv(csock, bufferRecv, sizeof(bufferRecv)-1, 0);
  51.                         if(error != SOCKET_ERROR)
  52.                         {
  53.                             bufferRecv[error] = '\0';
  54.                             color(12,0);
  55.                             printf("<<<< CLIEN DIT: %s\n",bufferRecv);
  56.                         }
  57.                         else
  58.                         {
  59.                             printf(":-/ Socket error, recv !\n" );
  60.                             go = 0;
  61.                         }
  62.                         char bufferSend[50];
  63.                         color(9,0);
  64.                         printf(">>>> SERVER DIT: " );
  65.                         fgets(bufferSend, sizeof(bufferSend), stdin);
  66.                         error = send(csock, bufferSend, strlen(bufferSend), 0);
  67.                         color(7,0);
  68.                         printf("\n...................Attente de la reponce du client (passiontez svp)....\n\n" );
  69.                         if(error == SOCKET_ERROR)
  70.                         {
  71.                             color(4,0);
  72.                             printf(":-/ Socket error, send !\n" );
  73.                             go = 0;
  74.                         }
  75.                     }
  76.                     shutdown(csock, 2);
  77.                     closesocket(csock);
  78.                     color(1,0);
  79.                     printf("::::: Client socket %d is now closed.\n",csock);
  80.                 }
  81.                 else
  82.                 {
  83.                     color(4,0);
  84.                     printf(":-/ Invalide Socket, error in opening Client socket\n" );
  85.                     system("pause" );
  86.                     return EXIT_FAILURE;
  87.                 }
  88.             }
  89.         }
  90.         closesocket(sock);
  91.         color(1,0);
  92.         printf(":::: Server socket %d is now closed.\n",sock);
  93.     }
  94.     else
  95.     {
  96.         color(4,0);
  97.         printf(":-/ Invalide Socket, erreur in opening Server socket\n" );
  98.         system("pause" );
  99.         return EXIT_FAILURE;
  100.     }
  101.     WSACleanup();
  102.     color(7,0);
  103.     system("pause" );
  104.     return EXIT_SUCCESS;
  105. }


 
merci
 
 
 

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed