Emmanuel Delahaye C is a sharp tool | thanks33 a écrit :
ma partie serveur ressemble a ceci
Code :
- // Attend une demande de connection
- do
- erreur=listen(id_de_la_socket,1);
- while(erreur!=0);
- cout << "listen : OK\n";
|
|
On ne fait pas de boucle sur listen(). On fait une boucle sur accept() (qui est bloquante).
A lire de A à Z : http://www.bien-programmer.fr/reseaux.htm
BUG : pour accept(), il faut fournir un sin (csin : client sin) différent de celui du serveur (ssin : server sin).
Ceci devrait mieux fonctionner :
Code :
- #include <stdlib.h>
- #include <stdio.h>
- #include <winsock2.h>
- int main (void)
- {
- int ret = EXIT_SUCCESS;
- /* Initialisation */
- WSADATA initialisation_win32;
- int erreur = WSAStartup (MAKEWORD (2, 2), &initialisation_win32);
- if (erreur != 0)
- {
- printf
- ("Desole, je ne peux pas initialiser Winsock du a l'erreur : %d %d\n",
- erreur, WSAGetLastError ());
- ret = EXIT_FAILURE;
- }
- else
- {
- /* Création de la socket */
- SOCKET ssock = socket (AF_INET, SOCK_STREAM, 0);
- printf ("WSAStartup : OK\n" );
- if (ssock == INVALID_SOCKET)
- {
- printf
- ("Desole, je ne peux pas creer la socket du a l'erreur : %d %d\n",
- erreur, WSAGetLastError ());
- ret = EXIT_FAILURE;
- }
- else
- {
- SOCKADDR_IN ssin;
- printf ("socket : OK\n" );
- /* Ouverture du port */
- ssin.sin_family = AF_INET;
- ssin.sin_addr.s_addr = INADDR_ANY;
- ssin.sin_port = htons (10000);
- erreur = bind (ssock, (struct sockaddr *) &ssin, sizeof (ssin));
- if (erreur != 0)
- {
- printf
- ("Desole, je ne peux pas me lier a ce port : %d %d\n",
- erreur, WSAGetLastError ());
- ret = EXIT_FAILURE;
- }
- else
- {
- printf ("bind : OK\n" );
- /* Le port est mis en ecoute */
- erreur = listen (ssock, 1);
- if (erreur == SOCKET_ERROR)
- {
- printf
- ("Desole, je ne peux pas ecouter ce port : %d %d\n",
- erreur, WSAGetLastError ());
- ret = EXIT_FAILURE;
- }
- else
- {
- printf ("listen : OK\n" );
- /* En attente de connexion d'un client */
- {
- SOCKADDR_IN csin;
- int tempo = sizeof (csin);
- SOCKET csock =
- accept (ssock, (struct sockaddr *) &csin, &tempo);
- if (csock == INVALID_SOCKET)
- {
- printf
- ("Desole, je ne peux pas accepter la session TCP du a l'erreur : %d %d\n",
- erreur, WSAGetLastError ());
- ret = EXIT_FAILURE;
- }
- else
- {
- char buffer[4096];
- long buffer2;
- /* Reçoit la longueur du nom du fichier (4 octet ou 32 bits) */
- int nombre_de_caractere;
- printf ("accept : OK\n" );
- /* -ed- pas portable ! */
- nombre_de_caractere =
- recv (csock, (char *) &buffer2, 4, 0);
- if (nombre_de_caractere <= 0)
- {
- printf
- ("Erreur, je n'ai pas recu la longueur du nom de fichier ! \n\n" );
- ret = EXIT_FAILURE;
- }
- else
- {
- char *nomdefichier;
- printf ("la longueur du nom de fichier est %ld\n",
- buffer2);
- /* Reçois le nom du fichier */
- nomdefichier = malloc (buffer2 + 1);
- if (nomdefichier != NULL)
- {
- /* -ed- Horriblement compliqué. Quel est le format des données ?
-
- Je recommande :
- (Codage des valeurs numériques : MSB en tete)
-
- [Origine:longueur]
-
- [0:2] LN : Longueur du nom de fichier (16-bit)
- [2:LN] Nom de fichier (chaine de caracteres)
- [2+LN:4] LD : longueur des données (32-bit)
- [6+LN:LD]Donnees
-
- */
- nomdefichier[0] = 0;
- {
- int i;
- for (i = 0; i < buffer2;
- i += nombre_de_caractere)
- {
- nombre_de_caractere =
- recv (csock, buffer,
- (buffer2 - i <
- 4096) ? buffer2 - i : 4096, 0);
- if (nombre_de_caractere == SOCKET_ERROR)
- {
- printf
- ("Erreur, je n'ai pas recu le nom du fichier !\n\n" );
- return EXIT_FAILURE;
- }
- else
- {
- int y;
- for (y = 0; y < nombre_de_caractere; y++)
- {
- nomdefichier[y + i] = buffer[y];
- nomdefichier[y + i + 1] = 0;
- }
- }
- }
- }
- printf ("Nom du fichier a recevoir : %s\n",
- nomdefichier);
- {
- FILE *fichiers = fopen (nomdefichier, "rb" );
- if (fichiers == NULL)
- {
- printf
- ("Erreur, impossible de créer le fichier !\n\n" );
- ret = EXIT_FAILURE;
- }
- else
- {
- /* Reçois la taille du fichier (4 octet ou 32 bits) */
- nombre_de_caractere =
- recv (csock, (char *) &buffer2, 4, 0);
- if (nombre_de_caractere <= 0)
- {
- printf
- ("Erreur, je n'ai pas recu la taille du fichier !\n\n" );
- return EXIT_FAILURE;
- }
- printf
- ("Taille du fichier a recevoir : %ld\n",
- buffer2);
- /* Reçois le fichier */
- {
- int i;
- for (i = 0; i < buffer2;
- i += nombre_de_caractere)
- {
- /* Si le nombre de donnée restant à reçevoir */
- nombre_de_caractere =
- recv (csock, buffer,
- (buffer2 - i <
- 4096) ? buffer2 - i : 4096
- /* est plus petit que le buffer on
- indique ce nombre sinon la taille
- du buffer */
- , 0);
- if (nombre_de_caractere ==
- SOCKET_ERROR)
- {
- printf
- ("Erreur, je n'ai pas recu le fichier !\n\n" );
- return EXIT_FAILURE;
- }
- else
- {
- fwrite (buffer, 1,
- nombre_de_caractere,
- fichiers);
- }
- }
- }
- fclose (fichiers);
- }
- }
- printf ("\nLe fichier a bien ete recu !\n\n" );
- }
- free (nomdefichier);
- }
- shutdown (csock, 2);
- closesocket (csock);
- }
- }
- }
- }
- shutdown (ssock, 2);
- closesocket (ssock);
- }
- WSACleanup ();
- }
- return ret;
- }
|
Il faut quand même revoir le mécanisme de réception des données...
Message édité par Emmanuel Delahaye le 11-06-2009 à 13:47:27 ---------------
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/
|