IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

WSASocket Probleme reception


Sujet :

Windows

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut WSASocket Probleme reception
    Bonsoir a tous,
    j'ai quelque problème d'envoi / réception de structure par socket.

    struct SocketStruct
    {
    char _type;
    char _buffer[1024];
    unsigned int _send;
    };


    En fait ca plante lors de transfert de fichier, a un moment dans unsigned int on a une valeur de l'ordre de 10^5 (je fait un new char[] sur cette valeur du coup segfault bien entendu).

    ca arrive rarement en local (souvent a distance !)

    voila ma fonction de réception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void		SocketTcpServer::Receive(void *Data, unsigned int Size)
    {
    	int		ret;
    	DWORD	dwBytesRet, dwFlags;
    	WSABUF	wbuf;
    	wbuf.len = Size;
    	wbuf.buf = (char *)Data;
    	dwFlags = 0;
    	ret = WSARecv(this->_socket, &wbuf, 1, &dwBytesRet, &dwFlags, NULL, NULL);
    	if (ret == 0)
    		return ;
    	throw Exception("SocketTcpSever", "Error WSARecv");
    }

    Merci d'avance.

    Cordialement,
    NeoKript

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Primo, envoyer des structures sur un réseau en utilisant dans type dont le taille et le endian est fonction de la plateforme, c'est pas très malin (cf. "unsigned int _send", il est de quel taille le unsigned int , 16, 32, 64 ? il est big ou little endian ?). Et Je ne parle même pas des problèmes d'alignement des champs de la structure.

    Donc SocketStruct, aux oubliettes, plouf !

    valeur de l'ordre de 10^5 (je fait un new char[]
    Oui mais il est ou le code qui fait new ?

    Secundo.
    La valeur de 10^5 est très vraisemblablement fausse, il faut donc juste chercher d'où elle vient. Par exemple une structure toute pourrie qui a un endian ou taille pour un unsigned int différent entre l'émetteur et le récepteur de la structure.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Salut et merci poru ta reponse.
    Tu me conseille donc quoi a la place des structure les structures c'est quand même pratique.

    Concernant le code qui fait le new :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    GString				GString::GetBuffer(const char *str, unsigned int size)
    {
    	std::cout << "SIZE     => " << size << std::endl;
    	GString s;
    	delete[] s._str;
    	s._size = size;
    	s._allocate = s._size + SIZE;
    	std::cout << "ALLOCATE => " << s._allocate << std::endl;
    	s._str = new char[s._allocate + 1];
    	unsigned int i = 0;
    	for (; i < size; ++i)
    		s._str[i] = str[i];
    	s._str[i] = 0;
    	return (s);
    }
    et l'envoie de fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    GFile f(Filename);
    f.Open(true);
    if !(f.IsOpen())
     return;
    while (!f.EndOfFile())
    {
    	GString r = f.Read(1024);
    	SocketStruct s;
    	strcpy(s._buffer, r.ToChar(), 1024);
    	s._send = r.Size();
            std::cout << s._send << std::endl;
            s._type = 3;
    	this->PushSend(s);
    }
    f.Close();
    Merci d'avance

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Primo : Si c'est pour s'ennoyer des messages, utilisez un protocole orienté message comme UDP.


    Secundo : je n'ai pas dit qu'il ne fallait pas utiliser des structures, j'ai juste dit qu'il faut connaitre les alignement, la taille, le endian etc. des champs de la structure. En clair, il faut savoir se que l'on fait.
    Il faut donc savoir où commence et où fini chaque champs au bit près, sur tous les compilateurs utilisés ou utilisables et sur toutes les plateformes (client et serveur, 32bits, 64bits, etc.).
    Par exemple
    /Zp http://msdn.microsoft.com/fr-fr/library/xh3e3fd0.aspx
    align http://msdn.microsoft.com/fr-fr/library/83ythb65.aspx
    C bit Fileds http://msdn.microsoft.com/fr-fr/library/yszfawxh.aspx
    Il faut aussi des nombres compréhensibles par tous :
    http://msdn.microsoft.com/en-us/libr...57(VS.85).aspx
    Votre structure est très très sous optimale. Pour envoyer un message de 1 octet, il faut utiliser au minimum (car ont compte pas les problèmes d'alignement des champs dans la structure) 1 + 1024 + 4 = 1029 octets.
    Si on n'est plus optimiste, on gâche en moyen 512 octets. C'est ENORME.
    Je vous conseil une approche bien plus simple de type TLV ou LTV (T pour type, L pour longueur et V pour valeur).
    Avec une approche TLV, le type à toujours la même longueur et est en tête de structure, la longueur permet de savoir où se fini V et donc de savoir très tôt si on à tout reçu ou pas. Si le type n'est pas connu on peut toujours passer au message suivant en interprétant le champ L.
    Avec une approche LTV, le champ longueur a toujours la même taille et est en tête de structure, cela permet de savoir où se fini V et donc de savoir très tôt si on à tout reçu ou pas. Si le type n'est pas connu, on peut toujours passer au message suivant. Cela permet aussi d'avoir un type de longueur variable et donc plus complexe.


    Tercio : On ne sait toujours pas d'où sort la valeur du paramètre size de la méthode GString::GetBuffer. S'il est faut c'est que l'appelant a merdé.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Merci beaucoup.

    Après modification (c'est long a faire) mais maintenant tout fonctionne et niveau rapidité c'est autre chose ! c'est vrai que maintenant que je n'alloue plus plus de 1000 octets pour 5 caractères !

    Merci en tout cas.

    Cordialement,
    NeoKript

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme reception de donnees par Socket
    Par herrs dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 10/07/2008, 11h29
  2. Réponses: 9
    Dernier message: 22/03/2007, 11h37
  3. Probleme reception avec utilisation de TComPort
    Par MDiabolo dans le forum C++Builder
    Réponses: 6
    Dernier message: 19/02/2006, 20h21
  4. Probleme reception de mail
    Par flouflou dans le forum Outlook
    Réponses: 2
    Dernier message: 20/07/2005, 10h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo