Socket envoi de fichier

Voir le sujet précédent Voir le sujet suivant Aller en bas

Socket envoi de fichier

Message  amine75 le Dim 23 Mai 2010 - 17:00

Bonjour,

Étant étudiant je dois coder en c une socket permettant l'envoi d'un fichier .txt

Je voulais savoir si vous pouviez m'aider a perfectionner mon code svp?
La taille du fichier est toujours la meme voici le code:

Code:

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 7
 
 
 
int main(void)
{

        int erreur = 0;
 //char buffer[]="bonjour";
char contenu_fichier[1024];
   int s;
int s_c;
    SOCKET sock;
    SOCKADDR_IN sin;
 
    if(!erreur)
    {
        /* Création de la socket */
        sock = socket(AF_INET, SOCK_STREAM, 0);
 
        /* Configuration de la connexion */
        sin.sin_addr.s_addr = inet_addr("192.168.109.72");
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);
 
        /* Si le client arrive à se connecté */
        if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
        else
            printf("Impossible_de_se_connecter\n");


   FILE* fichier = fopen("fichier.txt", "rb");

   while (fgets(contenu_fichier, sizeof(contenu_fichier), fichier) != NULL)
   {
   send(s, contenu_fichier, sizeof(contenu_fichier), 0);//il envoi ligne par ligne en binaire
   }
   send(s_c, "fini", sizeof("fini"), 0); // il envoi "fini" pour dir au client de que lenvoi est terminer
fclose(fichier);
}
}


Merci d'avance pour votre aider

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Dim 23 Mai 2010 - 17:35

Je suppose que c'est sous Linux !

Code:


-------------- Build: Debug in hello ---------------

Compiling: main.c
Linking console executable: bin\Debug\hello.exe
C:\dev\hello\main.c:3:28: sys/socket.h: No such file or directory
C:\dev\hello\main.c:4:28: netinet/in.h: No such file or directory
C:\dev\hello\main.c:5:27: arpa/inet.h: No such file or directory
C:\dev\hello\main.c: In function `main':
C:\dev\hello\main.c:31: error: storage size of 'sin' isn't known
C:\dev\hello\main.c:36: warning: implicit declaration of function `socket'
C:\dev\hello\main.c:36: error: `AF_INET' undeclared (first use in this function)
C:\dev\hello\main.c:36: error: (Each undeclared identifier is reported only once
C:\dev\hello\main.c:36: error: for each function it appears in.)
C:\dev\hello\main.c:36: error: `SOCK_STREAM' undeclared (first use in this function)
C:\dev\hello\main.c:39: warning: implicit declaration of function `inet_addr'
C:\dev\hello\main.c:41: warning: implicit declaration of function `htons'
C:\dev\hello\main.c:44: warning: implicit declaration of function `connect'
C:\dev\hello\main.c:45: warning: implicit declaration of function `inet_ntoa'
C:\dev\hello\main.c:45: warning: format argument is not a pointer (arg 2)
C:\dev\hello\main.c:50: warning: ISO C90 forbids mixed declarations and code
C:\dev\hello\main.c:54: warning: implicit declaration of function `send'
C:\dev\hello\main.c:31: warning: unused variable `sin'
Process terminated with status 1 (0 minutes, 0 seconds)
8 errors, 9 warnings
 
OK, j'ai fait une version Windows sur le modèle de http://www.bien-programmer.fr/reseaux.php#projet_reseau
Code:

        send (s, contenu_fichier, sizeof (contenu_fichier), 0); /* il envoi ligne par ligne en binaire */
      }
      send (s_c, "fini", sizeof ("fini"), 0); /* il envoi "fini" pour dir au client de que lenvoi est terminer */
s et s_c ne sont jamais initialisés ...

en fait il faut utiliser ce 'sock' :

Code:
      /* Création de la socket */
      sock = socket (AF_INET, SOCK_STREAM, 0);

Ceci devrait fonctionner (pas de serveur pour le tester...)
Code:

#ifdef __cplusplus
#error Be sure you are using a C compiler...
#endif

#if defined (WIN32) || defined (_WIN32)

#include <winsock2.h>

#elif defined (linux) || defined (_POSIX_VERSION) || defined (_POSIX2_C_VERSION)\
 || defined (_XOPEN_VERSION)

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>            /* close */

#define INVALID_SOCKET -1
#define SOCKET_ERROR -1

#define closesocket(s) close (s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;

#else
#error not defined for this platform
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* macros ============================================================== */

#define PORT 7

/* constants =========================================================== */
/* types =============================================================== */
/* structures ========================================================== */
/* private data ======================================================== */
/* private functions =================================================== */
/* entry point ========================================================= */

/* ---------------------------------------------------------------------
  --------------------------------------------------------------------- */
int main (void)
{
  int ret;

#if defined (WIN32) || defined (_WIN32)
  WSADATA wsa_data;
  int err = WSAStartup (MAKEWORD (2, 2), &wsa_data);

  if (!err)
  {
      puts ("WIN: winsock2: OK");
  }
#else
  int err = 0;
  {
#endif
      if (!err)
      {
        /* char buffer[]="bonjour"; */
        char contenu_fichier[1024];

        SOCKET sock;
        SOCKADDR_IN sin;

        /* Création de la socket */
        sock = socket (AF_INET, SOCK_STREAM, 0);

        /* Configuration de la connexion */
        sin.sin_addr.s_addr = inet_addr ("192.168.109.72");
        sin.sin_family = AF_INET;
        sin.sin_port = htons (PORT);

        /* Si le client arrive à se connecté */
        if (connect (sock, (SOCKADDR *) & sin, sizeof (sin)) != SOCKET_ERROR)
        {
            printf ("Connexion à %s sur le port %d\n",
                    inet_ntoa (sin.sin_addr), htons (sin.sin_port));
            {
              FILE *fichier = fopen ("fichier.txt", "rb");

              if (fichier != NULL)
              {
                  while (fgets
                        (contenu_fichier, sizeof (contenu_fichier),
                          fichier) != NULL)
                  {
                    send (sock, contenu_fichier, sizeof (contenu_fichier), 0); /* il envoi ligne par ligne en binaire */
                  }
                  send (sock, "fini", sizeof ("fini"), 0); /* il envoi "fini" pour dir au client de que lenvoi est terminer */
                  fclose (fichier);
              }
              else
              {
                  printf ("Fichier inconnu\n");
              }
            }
        }
        else
        {
            printf ("Impossible de se connecter\n");
        }
      }
#if defined (WIN32) || defined (_WIN32)
      WSACleanup ();
#else
  }
#endif

  if (err)
  {
      ret = EXIT_FAILURE;
  }
  else
  {
      ret = EXIT_SUCCESS;
  }

  return ret;
}
Il manque le code de déconnexion. Tout est expliqué dans le lien que je t'ai passé au-dessus...

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Dim 23 Mai 2010 - 22:30

Pourriez-vous commentez ligne par ligne pour que je comprenne mieux svp?

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Dim 23 Mai 2010 - 22:34

Non, parce que l'article que j'ai passé en référence explique tout de A à Z et pas à pas. Il suffit de le lire.

Qu'est-ce que tu ne comprends pas exactement ?

Je n'ai quasiment pas modifié ton code (juste rendu compatible Windows/Linux).

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Dim 23 Mai 2010 - 23:01

justement je dois le faire uniquement sous linux!

Pensez-vous que mon code est 'propre'?

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Dim 23 Mai 2010 - 23:16

Non, mais j'explique dans mon article comment envoyer correctement un fichier texte...

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Dim 23 Mai 2010 - 23:38

ok! demain je vais refaire ma socket en fonction de votre article et vous me direz ce que vous en pensez ok?

Merci d'avance

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Lun 24 Mai 2010 - 11:16

OK, ça me parait être une attitude raisonnable !

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Lun 24 Mai 2010 - 12:47

voila mon nouveau code aprés avoir lu votre article

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close (s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define PORT 23
#define IP "127.0.0.1"

void client (void)
{
/* Ouverture de la socket en TCP/IP*/
SOCKET sock= socket (AF_INET, SOCK_STREAM, 0);
if (sock != INVALID_SOCKET)
{
/*Configuration de la connexion*/
int err;
int s;
char contenu_fichier[1024];
SOCKADDR_IN sin = {0};
sin.sin_addr.s_addr = inet_addr (IP);
sin.sin_family = AF_INET;
sin.sin_port = htons (PORT);

/*Connection*/
err = connect (sock, (SOCKADDR *) & sin, sizeof (sin));
if (err != SOCKET_ERROR)
{
FILE * fichier;
fichier = fopen("fichier.txt", "rb");
while (fgets(contenu_fichier, sizeof(contenu_fichier), fichier) != NULL)
{
send(s, contenu_fichier, sizeof(contenu_fichier), 0);
}
else
{
printf ("ERR: send()\n");
}
fclose(fichier);
}
else
{
printf ("ERR: connect()\n");
}
closesocket (sock);
}
else
{
printf ("ERR: socket()\n");
}

}

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Lun 24 Mai 2010 - 12:58

J'avais fait l'effort d'écrire du code portable (je suis sous Windows ...)

Il faut définir un protocole pour transférer le fichier (au minimum, une en-tête avec nom et taille, un acquittement...). Quel est-il ?

Code:

FILE * fichier;
fichier = fopen("fichier.txt", "rb");
while (fgets(contenu_fichier, sizeof(contenu_fichier), fichier) != NULL)
{
send(s, contenu_fichier, sizeof(contenu_fichier), 0);
}
1 - fopen() peut échouer. (fichier vaut alors NULL). J'avais indiqué comment faire dans un post précèdent.
2 - Il n'y a aucune raison d'ouvrir un fichier texte en mode binaire. C'est donc "r" et non "rb".
3 - On doit transmettre des lignes de textes (complètes ou non, mais rien d'autre). Ce qui est après le "\n" ne doit donc pas être transmis. (je suppose que tu sais comment fonctionne fgets()). Il faut donc utiliser strlen() et don sizeof dans le send().
4 - send() peut échouer (retourne <0). Il faut le tester.

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Lun 24 Mai 2010 - 13:03

j'avou que je suis un peu perdu la! No

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Lun 24 Mai 2010 - 13:06

Il faut être plus précis dans tes remarques, sinon, je ne peux pas répondre. Qu'est-ce qui est compliqué ? Qu'est-ce que tu ne comprends pas ?

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Lun 24 Mai 2010 - 13:09

Le fgets() me pose problème! je n'arrive pas a l'utiliser

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Lun 24 Mai 2010 - 13:23

C'est à dire ? Il faut formuler des question précises avec des exemples si nécessaires, sinon, je ne peux pas répondre. As-tu lu la doc de fgets() ?

http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html

Je donne des détails ici :

http://www.bien-programmer.fr/notes.php#saisie

Je te conseille de commencer par réaliser un programme qui lit un fichier texte lignes à lignes (à supposer que c'est bien un fichier texte que tu veux transmettre). Si c'est un fichier binaire, la stratégie est différente et on utilise bien le mode "rb" mais avec la fonction fread() au lieu de fgets().

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  amine75 le Lun 24 Mai 2010 - 13:58

puis-je vous envoyer le fichier.txt?

Comme ca vous pourrai visualiser son contenu!

amine75

Messages : 8
Date d'inscription : 23/05/2010

Voir le profil de l'utilisateur

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  -ed- le Lun 24 Mai 2010 - 14:13

Oui, sur mon email en P.J.

emmanuel dot delahaye at gmail dot com

_________________
C is a sharp tool !

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Socket envoi de fichier

Message  Contenu sponsorisé Aujourd'hui à 15:28


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum