begin process at 2012 05 29 17:01:37
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Windows

 > 

Réseau & Internet

 > 

Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

samedi 5 juin 2010 à 01:56:59 | Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

nostalgius

Salut tout le monde..
Là je tente d'envoyer une image (simple exemple) avec send(), une image étant un fichier binaire elle contient des caractère non-imprimable tel que le '\0' (caractère nul) et là mon send() s'arrête sur le premier '\0' rencontré.
quelqu'un a une solution ?
(à part recourir à un encodage base64 ou quelque chose de semblable).

Merci d'avance.

:: un simple curieux ::
samedi 5 juin 2010 à 10:32:46 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

TychoBrahe

Réponse acceptée !
Salut,

Je serai curieux de voir ton code, en particulier la manière donc tu calcules la longueur de la chaîne à envoyer. Si tu utilises un strlen() pour calculer cette longueur alors il est parfaitement normal que ça s'arrête au premier \0 rencontré.
samedi 5 juin 2010 à 11:59:51 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

nostalgius

Merci!! en faite j'utilisai strlen() pour spécifier la taille des données à envoyer, là je donne comme paramètre la taille de mon fichier et ça marche!!
Merci encore

Voici ma fonction envoi_fichier, si vous avez des remarques pour
samedi 5 juin 2010 à 12:08:17 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

nostalgius

Merci!! en faite j'utilisai strlen() pour spécifier la taille des données à envoyer, là je donne comme paramètre la taille de mon fichier et ça marche!!
Merci encore

Voici ma fonction envoi_fichier, si vous avez des remarques pour l'améliorer:

Code C/C++ :
int envoi_fichier(SOCKET sur_socket, char* fichier)
{
    FILE *p_fichier;

    p_fichier = fopen(fichier, "rb");
        if (p_fichier == NULL) return 0;
            puts("\n\touverture fichier source");
            int longueur = 0;
            while (!feof(p_fichier))
            {
                fgetc(p_fichier);
                longueur++;
            }
    fclose(p_fichier);

    printf("\n\ttaille fichier: %d", longueur);
    unsigned char* contenu_fichier;
    contenu_fichier = malloc(longueur*sizeof(char));
    puts("\n\tinitialisation conteneur");
    int i;
    for(i=0; i<longueur+1; i++) contenu_fichier[i]= '\0';

    p_fichier = fopen(fichier, "rb");
        if (p_fichier == NULL) return 0;
        i=0;
        while (!feof(p_fichier))
        {
            contenu_fichier[i] = fgetc(p_fichier);
            i++;
        }
    fclose(p_fichier);

    char t_donnees_a_envoyer[10] = {0};
    sprintf(t_donnees_a_envoyer, "%d", longueur);
    if(send(sur_socket, t_donnees_a_envoyer, strlen(t_donnees_a_envoyer), 0) == SOCKET_ERROR) return 0;
    if(send(sur_socket, &t_donnees_a_envoyer[strlen(t_donnees_a_envoyer)+1], 1, 0) == SOCKET_ERROR) return 0;
    if(send(sur_socket, contenu_fichier, longueur ,0) == SOCKET_ERROR) return 0;

    free(contenu_fichier);
    return 1;
}
samedi 5 juin 2010 à 14:52:21 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

TychoBrahe

Merci encore


De rien ;)

si vous avez des remarques pour l'améliorer


Oui, mapper le fichier en mémoire est bien plus efficace. A noter que mmap() n'existe aps sous windows, il temfaudra regarder les différentes documentation pour trouver un équivalent (j'ai connais un pour le C++ sous windows mais pas pour le C).

Un exemple d'implémentation sur un système GNU/Linux :
Code C/C++ :
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int             send_file(int so, const char *file)
{
  struct stat   st;
  int           fd;
  int           nbw;
  char          *addr;

  fd = open(file, O_RDONLY);
  if (fd == -1)
    {
      perror("open");
      return -1;
    }
  fstat(fd, &st);
  addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (addr == MAP_FAILED)
    {
      perror("mmap");
      return -1;
    }
  nbw = send(so, addr, st.st_size, 0);
  if (nbw != st.st_size)
    {
      perror("send");
      munmap(addr, st.st_size);
      return -1;
    }
  return munmap(addr, st.st_size);
}
samedi 5 juin 2010 à 14:55:25 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

TychoBrahe

Errata: j'ai oublié le close() (à ajouter juste après le mmap().

Avec les lignes précédentes et suivantes ça donne :
Code C/C++ :
  /* ... */
  addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  close(fd);
  if (addr == MAP_FAILED)
  /* ... */
jeudi 24 juin 2010 à 11:07:10 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

nostalgius

Re TychoBrahe.
Désolé pour mon retard. je suis un peu débordé ces derniers temps .
Je vais essayer de trouver une équivalente sous Windows. en attendant ça consiste en quoi "mapper le fichier en mémoire"
Dslé encore et Merciii
jeudi 24 juin 2010 à 11:28:17 | Re : Problème envoi chaine binaire: send() s'arrête sur le premier '\0' rencontré

TychoBrahe

Salut,

en attendant ça consiste en quoi "mapper le fichier en mémoire"


Tout simplement à le charger dans la mémoire afin d'y avoir directement accès. Bref, tu récupère un pointeur vers un espace mémoire contenant le fichier. Pour caricaturer, c'est un peu comme un gros malloc dans lequel on copie le fichier. La différence la plus notable est que mmap est bien plus "intelligent" (optimisation de l'utilisation réel de la mémoire etc).

Quelques liens :
mmap() sur Wikipedia
man 2 mmap


Cette discussion est classée dans : send, binaire, premier, rencontré, arrête


Répondre à ce message

Sujets en rapport avec ce message

premier prog C++ graphique et Dev C++ 4.0 [ par zoophage ] Salut !je suis plus ou moins débutant en C++ et c'est pour ça que j'utilise dev c++ qui a le mérite d'être gratuit et facile à utiliser.Seulement, voi Mettre une fenette en premier plan et l'activer [ par atao ] QQun connait il une façon plus élégnate pour mettre une fenette en premier plan et l'activervoid MettreFenetreDevant(HWND hwndDlg){// car si elle est Compilation avec G++ [ par merlin ] voila je bosse sous beos linux bref sous unix et n'arrive pas a creer un fichier binaire mais pas elf ni a.out un binaire ( code machine ) y a t'il kk BINAIRE [ par lahou ] Comment peut-on faire pour avoir le code binaire d'un caractère ?MerciLahouPS : g pas trouvé ds les sources ni ds le forum !!! telecharger un fichier [ par Xs ] On fait comment pour telecharger un fichier ?je suppose qu'il faut demander au serveur de l'ouvrir en binaire puis utiliser une boucle du typewhile(!f Lire et ecrire dans un fichier en mode binaire [ par vbnul ] Je cherche comment lire et ecrire dans un fichier en mode binaire car on ne peut lire certains "caracteres" binaires dans les EXE par exemple.qqn pour Quelle API pour mettre en premier plan une autre fenetre ? [ par Kheo ] Afin d'eviter d'avoir plusieurs instance de mon soft en memoire au tout debut j'effectue un FindWindow sur le titre de mon soft. S'il ne trouve rien j HELP !!! Après plantage fichiers cpp transformés en binaire : code perdu !!!!! [ par ngryman ] J'y crois pas ! J'ai lancé mon progrmme, il a planté, une erreur windows s'est produite et j'ai redémarré mon pc, et après le fichier cpp principal de Envoi d'un mot binaire [ par seblutfr ] Bonjour à tous,Je suis en train de préparer en VB une appli qui se charge de créer un mot binaire de 25 éléments. Ce mot doit ensuite être envoyé vers conversion decimal binaire sans connaitre la taille du nombre [ par kobee12 ] Est ce que quelqu'un pourrait m'aider. Voici un algo qui convertit un nombre binaire en decimal :bin_digits est defini avec une taille de 10. Or j'aim


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,608 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales