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 :

Socket sous windows


Sujet :

Windows

  1. #1
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut Socket sous windows
    Bonjours,

    Je suis en train de créer une interface client / serveur Multi Plate Forme.
    J'ai donc un serveur qui envois des messages a l'aide de la fonction send et un client qui les recoit avec recv...
    cependant je suis embeter car sous linux, un appel a la fonction send correspond a un appel a la fonction recv mais ceci n'est pas valable sous windows...
    En effet, parfois il lit 2 messages en meme temps, comme si ils provenaient d'un seul et meme envoit. Cela est surement du au fait que l'ecriture se fais plus fite que la lecture, et donc la fonction recv continue de lire sur le flux.

    Y a t'il un moyen pour que la fonction send envois une sorte de fin d'envois detecter par la fonction recv sous windows ou bien est ce que je doit coder cela moi meme ?

    Merci

  2. #2
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Pas calé dans le domaine... Mais il me semble effectivement que recv assemble tous les paquets reçu dans un flux continu... Un peu comme un flux sur un fichier...

    Dans ton cas j'aurais effectivement cherché quel séparateur de message pourrait être utilisé (\0 dans le cas de messages textes, etc...)

    A mon (humble) avis, tu a le choix entre un flot continu et une gestion bas niveau des paquets, un par un (et avec les aléas d'ordre de réception que ça implique...) Mais je me répète : pas expert, peu me tromper...

    As-tu tenté de poser la question dans le forum "devellopement Windaube", puisque ton titre laisse pensé que c'est lui qui fait les recv()s ?

  3. #3
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Je vais surement etablir une sorte de séparateur si je ne trouve pas d'autres solutions en effet...

    Je ne poste pas dans le forum windows car le multipost est interdit et je pense que le forum C++ est plus aproprié
    Ceci dit si je laissera un modérateur déplacer ce post si jamais il conviendrais a un autre forum

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Points : 288
    Points
    288
    Par défaut
    Tu travailles sur un socket TCP vu que tu utilises les send()/recv() (ou alors en UDP connecté c'est possible aussi mais bon plus rare).
    Tu es sûr que la fonction recv() sous windows à se comportement ? Ca me paraît très étrange.

    Sinon à la création de ton socket (l'appel à la fonction socket()) tu peux essaier les options suivantes :
    Pour le premier paramètre (qui devrait être chez toi PF_INET) tu peux tenter un PF_PACKET. Attention tu passes en gestion bas niveau des packet. Jamais utilisé personnellement mais à toi de voir ce que ca implique. Je ne sais même pas en fait si cette option te permet d'envoier des packets sur internet, et surtout si elle n'est pas spécifique à Linux. Bref teste le reste avant je pense

    SOCK_SEQPACKET en 2nd paramètre (où tu dois avoir un SOCK_STREAM). SOCK_SEQPACKET est normalement déprécié mais bon : Encore une fois j'ai jamais utilisé.
    Tu peux aussi envisager de passer en SOCK_DGRAM (UDP), j'ai codé en réseau sous linux & windows toujours en SOCK_DGRAM (en intégrant mes propres routines de vérification de l'intégrité des données, de l'ordonnancement etc) et je n'ai jamais eu le genre de problème que tu décris.
    En dernier recours (ou enfait peut-être juste avant de tenter le SOCK_SEQPACKET) tu peux tenter les SOCK_RAW. Nécessite les droits d'admins souvent. Tu forges tes propres packets à la main. A ce moment là tu peux repasser en TCP si tu préfères en forgeant tes packet à la main. Avec les winsock il y a quelques soucis si je me souviens bien, il bidouille un truc dans ton entête IP malgré tout A vérifier.

    Ensuite je ne sais pas exactement jusqu'à quel niveau Windows respecte la norme POSIX (voir même là on est limite en 4.4 BSD) mais tu as l'option SOCK_RDM aussi qui te permet d'avoir un socket pseudo-UDP qui garantit le fait que ca arrive mais qui ne garanti pas l'ordre.

    Voilà quelques pistes pour orienter tes recherches. Je ne peux pas t'en dire beaucoup plus sinon que toutes les applis réseau que j'ai codé étaient en SOCK_DGRAM et que je n'ai jamais eu de problèmes tels que le tien.

    Bonne chance

  5. #5
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    ou alors en UDP connecté c'est possible aussi mais bon plus rare
    tu es sûr ?

  6. #6
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    A lire Yabo je suis tout faux...
    Souvenir théorique et surtout très flous...
    Mais j'aime pas les posts qu'on zéro réponses, et pis ça les remet en tête de liste

    Merci Yabo pour ces précisions instructives !!!

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Points : 288
    Points
    288
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    ou alors en UDP connecté c'est possible aussi mais bon plus rare
    tu es sûr ?
    De quoi ? Que les sockets UDP connecté existent (oui ca fait un choc je sais ) ? Oui ca existe

    Voici le lien qui le confirme.

  8. #8
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    J'arrive pas à aller à ton lien. Mais je suis surpris, quel est l'intérrêt de ça ? TCP est là, si UDP fait pareil c'est quoi le but ? T'es sûr que c'est pas le bonhomme qui à la main se gère la connexion ?
    http://www.speedguide.net/faq_in_q.php?category=97&qid=144

  9. #9
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Merci de vos réponses je suis pas en mesure physiquement de tester tout de soute toute ces solutions mais j aurais toutefois quelques petites infos à demander au passage.

    Oui je confirme bien ce comportement sous windows car pour débugger mon prog j'ai afficher le contenu de mes recv et j'ai bien remarquer que les 3 étaient recu dans le meme appel :/

    Je recherche surtout la rapidité et il parait que l'UDP est plus rapide que le TCP à ce niveau la. Par contre dans la théorie on m'as dit qu'en UDP on a pas de certitudes sur l'arrivée des paquets ni sur leurs integrités... J'avoue que cela m'as fais peur et que je ne me suit dont pas penché sur le sujet... Est ce que quelqu'un aurais des sites ou des infos a ce sujet ? (Note : Si le sujet est déja traité dans la FAQ inutile de répondre, j y vais de ce pas )

    Je vous donne des nouvelles des que j en ai

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    J'arrive pas à aller à ton lien
    Bon le lien est revenu. J'en comprend qu'une socket UDP connecté c'est juste un mécanisme pour simplifier l'envoie de donneées vers une unique destination. Mais UDP reste un protocole non connecté, seule la socket l'est. C'est un alias en gros.

  11. #11
    Nouveau membre du Club
    Profil pro
    Développement
    Inscrit en
    Janvier 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développement

    Informations forums :
    Inscription : Janvier 2005
    Messages : 15
    Points : 30
    Points
    30
    Par défaut
    Pour moi, si tu es en TCP, ce comportement est tout à fait normal car en TCP, il faut oublier la notion de paquet. Si tu fais 3 send() d'affilé, tu peux récupérer le contenu des 3 envoies en un seul appel à recv() car la couche TCP va concaténer les messages entre eux à leur arrivée. Voire même, tu peux recevoir le contenu du premier et la moitié du second (c'est un poin tà ne pas oublier).

    Il me semble même que la concaténation peut avoir lieu à l'envoi : si on appelle la fonction send() avec un petit buffer, la couche TCP attend un peu avant de l'envoyer et si un autre appel à send() est fait dans ce laps de temps, les 2 messages sont concaténés. Ceci afin de limiter les nombreux envois de petites trames. C'est le "Nagle algorithm" me semble-t-il.

    Pour ton problème, je vois deux solutions :

    - soit tu passes en UDP et tu auras bien une requete par trame donc par recv() par contre tu devras gérer toi-même les connexions et pertes de paquet.
    - soit tu restes en TCP et tu insères un mécanisme qui permet de retrouver le début et la fin de chacune de tes requetes.

  12. #12
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    en effet, en TCp, la notion de paquet n'existe plus, ce que tu reçois est un flux.
    Pour délimiter, 2 solutions :
    soit tu définis un charactere "null" qui dit que c'est la fin de la chaine (comme \0 pour un char*)
    soit, plus simple je pense :
    tu dis que tes 2 premiers octets sont une taille....
    Et ainsi, quand tu lis :
    tu fais un :

    (algo formel)
    unisgned short taille = receive(2);
    char[] tableaudonnees = receive(taille);
    et la tu es sur de ton coup...

    PS : méfie toi du bigendian/littleendian

  13. #13
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Je pense que cette solution est la plus simple et la plus rapide a implémenté dans mon projet dans un premier temps.

    En ce qui concerne les problemes de little/big endian 32 / 64 bits je vais réglere ca en passant mes données en ASCII en attendant de trouver mieux tout en restant stable...

    Petite question cepandant : Est on vraiment certain du transit des données ou non selon vous ? J'entend par la que si jamais une erreur apparait dans le bit de lecture de longueur ca risque de poser un serieux probleme par la suite. Est ce que je peux me fier a ca ou bien est ce que je doit gérer un cas d'erreur pour pourvoir m'y retrouver dans mon flux ?

  14. #14
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    tu peux t'y fier : le TCP gere un checksum qui rejette le paquet si le checksum n'st pas correct (il s'appuie sur CRC)
    la probabilité qu'un paquet foireux arrive, et apparaisse valide (bien qu'elle ne puisse bien sur pas etre totalement nulle) est excessivement faible : tu peux vraiment t'y fier.

  15. #15
    Nouveau membre du Club
    Profil pro
    Développement
    Inscrit en
    Janvier 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développement

    Informations forums :
    Inscription : Janvier 2005
    Messages : 15
    Points : 30
    Points
    30
    Par défaut
    Effetivement, on peut s'y fier.

    Je rajouterai juste que si le paquet est rejeté par la couche TCP, une demande est envoyé à l'expéditeur pour qu'il renvoie le paquet mal reçu. Tu ne risques donc pas d'avoir des trous dans tes trames. Tu n'as donc pas à te soucier de svoir si la requete a été reçue ou non.

  16. #16
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Points : 288
    Points
    288
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    J'arrive pas à aller à ton lien
    Bon le lien est revenu. J'en comprend qu'une socket UDP connecté c'est juste un mécanisme pour simplifier l'envoie de donneées vers une unique destination. Mais UDP reste un protocole non connecté, seule la socket l'est. C'est un alias en gros.
    Je n'ai jamais pretendu le contraire, mais il est possible de "connecter" son socket UDP. Ca a son utilite dans certain cas. Mais oui le protocole UDP est par definition un protocole non-connecte.

    Citation Envoyé par Higestromm
    Je recherche surtout la rapidité et il parait que l'UDP est plus rapide que le TCP à ce niveau la. Par contre dans la théorie on m'as dit qu'en UDP on a pas de certitudes sur l'arrivée des paquets ni sur leurs integrités... J'avoue que cela m'as fais peur et que je ne me suit dont pas penché sur le sujet... Est ce que quelqu'un aurais des sites ou des infos a ce sujet ? (Note : Si le sujet est déja traité dans la FAQ inutile de répondre, j y vais de ce pas )
    TCP : Ton packet est sur d'arriver, d'arriver integre et que les donnees arrivent dans l'ordre d'envoi. Le probleme est que pour garantir tout ca le TCP est un protocole "lourd".
    UDP : La seule certitude que tu as c'est que ton packet est envoie. Une fois qu'il a quitte physiquement ton PC tu en perds completement la trace. Seulement il ne faut pas se leurrer, je ne saurais pas te dire un chiffre comme ca mais beaucoup de packets arrivent a destination, integre et dans le bon ordre.

    L'avantage d'UDP c'est qu'il est tres leger, il n'y a que ce que tu as dis d'envoier qui est effectivement envoie.
    Dans toutes mes applis j'ai classe mes packets en 2 categories, les critiques et les non-critiques. Pour les packets critiques j'ai reimplemente mes propres fonctions de gestion de l'integrite etc. La ou je gagne donc ce sont sur les packets non-critiques essentiellement.
    Citation Envoyé par Higestromm
    Je pense que cette solution est la plus simple et la plus rapide a implémenté dans mon projet dans un premier temps.
    En effet elle semble pas mal, j'ignorais le coup du flux pour le TCP, mais c'est bon a savoir
    Citation Envoyé par Higestromm
    En ce qui concerne les problemes de little/big endian 32 / 64 bits je vais réglere ca en passant mes données en ASCII en attendant de trouver mieux tout en restant stable...
    C'est resolument le plus portable et le plus elegant.

    PS : Desole pour les accents, qwerty

  17. #17
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 17
    Points : 20
    Points
    20
    Par défaut
    TCP est tres puissant
    Il gere le controle de flux, et de congestion, de façon a ce que, si un routeur ne peut faire passer que de petits paquets, il sait diviser les paquets, s'adapter a la vitesse des routeurs (ralentir et réaccelérer s'il faut), redemander les paquets perdus apres un timeout court, ne pas attendre un paquet avant de pouvoir encaisser le prochain : grouper les accusés de reception pour ne pas en avoir autant a lancer que de paquets reçus, paquets d'accusés, qui, en outre, contiennent l'info sur le prochain paquet a envoyer, ce qui permet au serveur de savoir ou il en est.
    TCP, s'il reçoit le paquet N+1 apres le paquet N, est capable de les remettre dans l'ordre, grace a un controle d'identifiant que gere le protocole.
    TCP gere en outre le CRC pour assurer a quasi 100% que les paquets validés par ce derniers soient fiables.

    Bref, plein plein de gros mécanismes !
    Et tout transparent :
    tout se passe apres comme un flux de données fiables envoyés en reçus

    Anecdote : une expérience a été faite, un gars roulait dans une jeep, par temps de pluie, avec un un émétteur assez pourri : le but étant de rendre la connexion difficile, et, TCP a réussi a s'adapter a cela pour faire en sorte que le mec reçoive toutes ses données, et correctement. Et TCP a fait ses preuves dans ce cas la aussi

  18. #18
    Membre averti Avatar de Higestromm
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    516
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 516
    Points : 412
    Points
    412
    Par défaut
    Je vous remercie tous pour vos réponses constructives

    Affaire conclus pour moi

    Reste pu qu'une chose à faire ... coder

  19. #19
    Nouveau membre du Club
    Profil pro
    Développement
    Inscrit en
    Janvier 2005
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développement

    Informations forums :
    Inscription : Janvier 2005
    Messages : 15
    Points : 30
    Points
    30
    Par défaut
    Juste pour préciser que pour les histoires de little et big endian, il existe les fonctions ntohs(), ntohl() qui permettent respectivement de coder un short et un long depuis l'ordre du réseau vers l'ordre de l'ordinateur hote et les fonctions htons() et htonl() qui font le contraire.

    Si tu utilises htons() à l'envoi et ntohs() à la réception, tu es assurés que tu auras la bonne valeur dans le bon format quelque soit la plateforme.

    Ca peut te permettre d'éviter les conversions ASCII/binaire.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Points : 473
    Points
    473
    Par défaut
    Citation Envoyé par Higestromm
    En ce qui concerne les problemes de little/big endian 32 / 64 bits je vais réglere ca en passant mes données en ASCII en attendant de trouver mieux tout en restant stable.
    Les fonctions ntoh et hton (resp. 'network to host' et 'host to network') permettent de régler les problèmes d'endianess.
    Elles ne sont pas standard, mais très largement implantées.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Programatopn socket sous windows avec VS 2012 en projet console
    Par tonycalv dans le forum Développement Windows
    Réponses: 0
    Dernier message: 15/01/2015, 23h41
  2. Utilisation des sockets sous Windows (VISTA)
    Par Linoux dans le forum Réseau
    Réponses: 5
    Dernier message: 06/03/2009, 16h26
  3. Programmation de socket sous windows
    Par chrix10.2 dans le forum Bibliothèques
    Réponses: 5
    Dernier message: 10/10/2007, 09h36
  4. socket sous windows
    Par youp_db dans le forum Windows
    Réponses: 3
    Dernier message: 29/08/2005, 15h53
  5. utilisation des sockets sous windows
    Par Tupac dans le forum Réseau
    Réponses: 2
    Dernier message: 21/12/2002, 18h24

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