Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Envoi d'un tableau de unsigned char avec des SocketUDP  (Lu 7364 fois)

0 Membres et 1 Invité sur ce sujet

thej

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Envoi d'un tableau de unsigned char avec des SocketUDP
« le: Avril 01, 2012, 02:30:23 pm »
Bonjour,

J'ai fait 2 programmes (Client/Serveur) qui s'échange des images sous formes de tableau (unsigned char).
Mais quand je lis le tableau et affiche sont contenu je trouve une image noire.
J'ai envoyé le tableau de toute les façon possible et imaginable sans jamais trouver la bonne solution. (En gros à la fin j'y suis aller au petit bonheur la chance  :P )

Donc en fait ma question est :
Comment envoyer un tableau de unsigned char avec des sf::SocketUDP ?
Merci d'avance pour votre aides  :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #1 le: Avril 01, 2012, 03:42:50 pm »
Tu devrais nous montrer ton code (la version que tu penses être la bonne), histoire qu'on ait une base pour commencer à discuter ;)
Laurent Gomila - SFML developer

thej

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #2 le: Avril 01, 2012, 03:55:15 pm »
Oui bien sur, alors celle que je pense là bonne serait celle là avec des paquets, la 1ere que j'ai faite:

Envoi :
unsigned char *data = (unsigned char*)cam->imageData;
paquet << *data;
serveur.EnvoiDonnes(paquet); //Exécute simplement SocketUDP.Send
paquet.Clear();

Réception :
if(Socket.Receive(paquet, adr, port) == sf::Socket::Done)
{
        unsigned char *dataTemp;
        paquet >> *dataTemp:
        /*
        Utilisation des données
        */
}

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #3 le: Avril 01, 2012, 04:03:33 pm »
Citer
paquet << *data;
Là tu envoies le premier octet de ton tableau.

Citer
unsigned char *dataTemp;
        paquet >> *dataTemp:
Là tu reçois le premier octet envoyé, dans un espace mémoire non alloué (ton pointeur dataTemp n'est pas initialisé).

Tu ne devrais pas utiliser les paquets, étant donné que tu utilises UDP et que tu envoies des données brutes, ils ne te servent strictement à rien. Tu peux tout simplement envoyer tes données directement avec la fonction Send qui prend en paramètre des données brutes, et les recevoir avec le Receive correspondant.

Ensuite il faut que tu sois conscient qu'avec UDP tu ne pourras pas dépasser la taille max d'un datagramme, à savoir un peu moins de 65536 octets. Il faudra donc découper en plusieurs envois si ton image est plus grosse.
Laurent Gomila - SFML developer

thej

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #4 le: Avril 01, 2012, 04:14:16 pm »
Citer
(ton pointeur dataTemp n'est pas initialisé)
Une erreur de ma part, je l'avais initialisé à la taille du tableau envoyer plus tôt.

Donc justement ma dernière solution que j'ai tester était :
Envoi :
unsigned char *data = (unsigned char*)cam->imageData;
char *dataChar = (char*)data;
serveur.EnvoiDonnes(dataChar, sizeof(dataChar));

//Je croit que c'était faisable en 2 ligne au lieu de 3 ^^'

Réception :
if(Socket.Receive(dataChar, sizeof(dataChar), recu, adr, port) == sf::Socket::Done)
{
    unsigned char *dataTemp = (unsigned char*)dataChar;
    /*
         Utilisation des données
    */
 }
Mais il doit y avoir une erreur car j'ai une image noire encore.

Seulement 65.536 octets O.o
Mon image fait 923.523 octets, sa fait 15 envois pour 1 image ...
Tu me conseillerais TCP alors ?
« Modifié: Avril 01, 2012, 05:18:46 pm par thej »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #5 le: Avril 01, 2012, 05:21:13 pm »
Citer
unsigned char *data = (unsigned char*)cam->imageData;
char *dataChar = (char*)data;
Autant faire le cast en char* directement, et avec reinterpret_cast (les casts type C sont à proscrire).

Citer
serveur.EnvoiDonnes(dataChar, sizeof(dataChar));
sizeof(dataChar) renverra 4 (ou 8 ), c'est la taille du pointeur et non de ce qui est pointé. Tu dois donner la taille explicitement, il n'y a que toi qui la connaisse, le compilo ne peut pas la deviner. Ce sera sûrement un truc du genre longueur * largeur * 3 (si ce sont des pixels RGB).

Citer
Socket.Receive(dataChar, sizeof(dataChar), recu, adr, port)
Même remarque, sizeof(dataChar) est incorrect. Si tu ne connais pas la taille côté client, il faudra que tu l'envoies avant les pixels.
Et il manque un truc à ce bout de code : l'initialisation de dataChar.
Laurent Gomila - SFML developer

thej

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #6 le: Avril 01, 2012, 06:43:54 pm »
Que d'erreurs que d'erreurs   :-[
Je débute dans le réseau, ne m'en voulez pas  ;)

Reprenons
Envoi :
char *data = reinterpret_cast<char*>(cam->imageData);
serveur.EnvoiDonnes(data, taille); //sf::Int32 taille est calculer et envoyer a client plus tot dans le programme

Réception :
char dataChar[taille]; //sf::Int32 Taille est envoyer un peut plus tot

if(Socket.Receive(dataChar, taille, recu, adr, port) == sf::Socket::Done)
{
       unsigned char *dataTemp = reinterpret_cast<unsigned char*>(dataChar);
       /*
         Traitement
      */
}

C'est déjà mieu  :)
Le programme ne rentre pas dans SocketUPD::Receive, euh ... sa veut dire quoi ?  ??? Qu'il ne reçoit rien ?

L'image fait 923.523 octets, il me faudrat donc 15 envois pour 1 image ?  :o
« Modifié: Avril 01, 2012, 07:14:37 pm par thej »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #7 le: Avril 01, 2012, 07:31:31 pm »
Citer
Je débute dans le réseau, ne m'en voulez pas
Ce ne sont que des erreurs de base de C++. En travaillant un peu plus ces bases avant d'attaquer le réseau tu aurais moins de problèmes, enfin ce n'est qu'un conseil ;)

Citer
char dataChar[taille]; //sf::Int32 Taille est envoyer un peut plus tot
Si ton compilo accepte ça c'est qu'il est mal reglé. Une taille de tableau doit être connue à la compilation, sinon il faut utiliser un tableau dynamique (std::vector).

Citer
Le programme ne rentre pas dans SocketUPD::Receive, euh ... sa veut dire quoi ?
Il ne rentre pas dedans, ou bien il n'en sort pas ? S'il ne rentre pas dedans alors l'erreur n'a rien à voir avec ça, et s'il n'en sort pas alors oui c'est quil ne reçoit rien.

Citer
L'image fait 923.523 octets, il me faudrat donc 15 envois pour 1 image ?
Oui. Faut pas avoir peur, UDP est justement fait pour ça ;)
Par contre pense à numéroter tes datagrammes, UDP ne garantit en effet pas la réception : tu peux donc avoir des datagrammes perdus, réordonnés, ou dupliqués.
Laurent Gomila - SFML developer

thej

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #8 le: Avril 02, 2012, 04:57:58 pm »
J'ai de bonne base en C++, mais j'évite souvent l'utilisation de pointeur (j'aime pas trop ça, mais j'ai très bien comprit leurs utilité), donc quand je me retrouve forcer à en utiliser je mélange un peut.
Mais c'est en forgeant que l'on devient forgerons, et je pense avoir les base pour forger :P
De plus que c'est vraiment une passions.

Citer
Si ton compilo accepte ça c'est qu'il est mal reglé.
Euh et bien il est mal régler, je vais voir ça  ???

Donc j'ai fait mon algorythme :
Envoi :
char dataEnv[50001]; //1 de plus octet pour le numero
int n = 0;
for(char i = 0 ; i <= 20 ; i++)
{
    dataEnv[0] = i;
    for(int j = 1 ; j < 50001 ; j++)
    {
        dataEnv[j] = dataU[n]; //Plus haut dans le programme : 'unsigned char dataU[1000000];'
        n++;
    }
    serveur.EnvoiDonnes(dataEnv, 50001);
}

Réception :
char dataChar[50001];
if(Socket.Receive(dataChar, 50001, recu, adr, port) == sf::Socket::Done)
{
    int num = dataChar[0] * 50000;
    for(int i = num ; i < (num+50000) ; i++)
    {
        data[i] = dataChar[i+1]; // data est un tableau de unsigned char de 1.000.000 cases
    }
}

Le 1er paquet arrive très bien et s'affiche bien.
Par contre les suivant m'affiche du noir avec quelque pixel de chaque couleur par ci par là.
Et au cinquième paquet le programme client plante (rapport d'erreur).
Mon algorithme contient une erreur ?  :-\

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #9 le: Avril 02, 2012, 05:56:25 pm »
Pour la réception, il faut lire dans dataChar de 0 à 50000 et non de num à num + 50000.
Laurent Gomila - SFML developer

minirop

  • Sr. Member
  • ****
  • Messages: 254
    • Voir le profil
    • http://dev.peyj.com
Re : Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #10 le: Avril 10, 2012, 01:17:46 am »
si "data" est un tableau de 10^6, ton code devrait pas plutôt être :
for(int i = 1; i < 50001; i++)
    {
        data[num + i] = dataChar[i]; // data est un tableau de unsigned char de 1.000.000 cases
    }

Lynix

  • Sr. Member
  • ****
  • Messages: 403
    • Voir le profil
Re : Re: Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #11 le: Avril 10, 2012, 09:18:12 am »
Citer
char dataChar[taille]; //sf::Int32 Taille est envoyer un peut plus tot
Si ton compilo accepte ça c'est qu'il est mal reglé. Une taille de tableau doit être connue à la compilation.

Être conforme au C99 est un mauvais réglage de compilateur maintenant ? ;D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #12 le: Avril 10, 2012, 10:09:42 am »
Citer
Être conforme au C99 est un mauvais réglage de compilateur maintenant ?
Être conforme au C99 pour un compilateur C++ est un mauvais réglage, oui.
Laurent Gomila - SFML developer

Lynix

  • Sr. Member
  • ****
  • Messages: 403
    • Voir le profil
Re : Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #13 le: Avril 10, 2012, 11:28:44 am »
It's not a bug, it's a feature :)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Envoi d'un tableau de unsigned char avec des SocketUDP
« Réponse #14 le: Avril 10, 2012, 11:32:37 am »
Pas si tu distribues ton code source sur d'autres environnements.
Laurent Gomila - SFML developer