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

Entrée/Sortie Java Discussion :

Créer un protocole de communication, TCP et UDP


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Créer un protocole de communication, TCP et UDP
    Je suis en train de créer une application "réseau" composée de 3 parties : client, serveur, protocole.
    Ces 3 parties sont aussi 3 projet différents sur Eclipse.
    Les projets client et serveur utilisent le projet protocole.
    (C'est une application de type contrôle à distance, mais ce n'est pas important ici).

    Pour le moment, la partie protocole utilise UDP pour plusieurs raisons :
    - latence plus faible (il parait)
    - découpage en "paquet" plus facile qu'en TCP (mais j'espère me tromper)

    Mais j'ai plusieurs problèmes avec UDP, et je vais peut être finalement utiliser TCP :
    - j'ai des pertes de paquets un peu gênantes
    - un bug sur ma plateforme "client" (Android), m'empeche de recevoir en UDP.

    Tout mon protocole est basé sur des données "binaires". Pas de texte, pas de xml. Je manipule les données grâce à la classe ByteBuffer.

    J'ai donc des questions en ce qui concerne cette migration UDP vers TCP

    Jusqu'à présent, pour une action "bouger la souris de tant de pixels", j'envoyais un paquet UDP.
    Comment reproduire la même notion de "paquet" dans TCP? Je crois que TCP fonctionne sur un système de "flux" continu.
    J'ai pensé à inclure avant chaque "action" envoyée, la taille en octets de cette action.

    Comment "forcer" l'envoi de "données en cache" dans TCP (pour éviter d'attendre qu'un buffer soit rempli avant l'envoie des données)? La latence est primordiale dans mon application :p


    Merciiii

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par PierreD87 Voir le message
    - latence plus faible (il parait)
    Non: la latence est la même avec TCP et UDP en fonctionnement 'normal'. La seule différence se situe quand il y a eu pertes de paquets, par exemple au paquet N : les paquets N+x (même s'ils sont reçus) ne seront pas délivrés à ton application tant que N n'a pas été redemandé et re-reçu.

    Ceci est dû au fait que TCP garantit également le bon ordre des paquets reçus (et ce n'est pas désactivable).

    - j'ai des pertes de paquets un peu gênantes
    Ben là il y a plus à hésiter : TCP ! Parce que si tu dois toi-même implémenter une surcouche à UDP pour gérer la perte / ré-émission de paquets, ça va vite devenir très complexe.

    Comment reproduire la même notion de "paquet" dans TCP? Je crois que TCP fonctionne sur un système de "flux" continu. J'ai pensé à inclure avant chaque "action" envoyée, la taille en octets de cette action.
    Exactement. Attention à bien coder la taille sur un nombre d'octets suffisant pour test besoins (exemple: 1 octet te limite à des tailles maxi de 256 octets ; 2 octets te limite à des paquets de 2^16 octets (65Ko), etc...).

    Comment "forcer" l'envoi de "données en cache" dans TCP (pour éviter d'attendre qu'un buffer soit rempli avant l'envoie des données)?
    Il faut passer par la désactivation de l'algorithme de Nagle. En Java, il faut appeler setTcpNoDelay(true) sur tes instance de Socket.

    Une fois ceci fait, il te faut faire très attention à n'effectuer qu'un seul appel à write() pour chaque paquet que tu veux émettre (y compris pour le bout d'octets représentant la taille du paquet). En effet, chaque appel à write() générera un paquet distinct.


    A noter que la même possibilité est offerte dans à peu près tous les langages ayant le support des sockets TCP.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Ok, merci beaucoup pour ces conseils !

    Le problème, avec le fait d'inclure la taille du "paquet virtuel" avant, c'est qu'il faut avoir 100% confiance dans l'application qu'on a en face :/
    Et aussi, le moindre petit bug de "décalage" dans le flux peut devenir vite catastrophique

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Le problème, avec le fait d'inclure la taille du "paquet virtuel" avant, c'est qu'il faut avoir 100% confiance dans l'application qu'on a en face :/
    Pas spécialement: si tu détectes côté serveur une taille de paquet farfelue (genre 100Mo alors que tu sais que tes paquets ne dépassent jamais quelques centaines d'octets), rien ne t'empêche de déconnecter immédiatement le client (plus ban d'IP et pendaison sur la place publique ).
    De plus, taille de paquet ou pas, TCP ou pas, il te faudra de toute façon vérifier systématiquement l'ensemble des données (présence & contenu) que le client envoie ; ce n'est finalement qu'un (tout petit) check supplémentaire.

    A la limite, si tu veux renforcer tes vérifications, une autre solution est d'inclure -avant même la taille du paquet- le type de message envoyé sur un nombre d'octets fixe; ainsi tu peux en plus vérifier que:

    - le type de paquet fait partie des paquets susceptibles d'être envoyés à ce moment là par le client.

    - la taille du paquet est cohérente avec le type de paquet.

    Et aussi, le moindre petit bug de "décalage" dans le flux peut devenir vite catastrophique
    Oui, mais:

    - TCP te garantit qu'il n'y aura aucune altération du contenu entre ce qui est émis et ce qui est reçu. Donc de ce côté, t'es peinard.

    - une fois cette partie codée (elle est commune au client et au serveur et pas bien complexe au final) et bien testée, tu n'as plus à y toucher et ça roulera sans souci.

    - bien entendu, il faut bien veiller à ce que cette gestion des paquets envoyés est encapsulée dans ton API: aucune autre partie du programme ne doit pouvoir fourrer son nez dedans hormis la classe 'bas niveau' qui s'occupe de gérer concrètement la socket. A noter que ceci pourrait te donner quelques idées pour une approche 'par couches'.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Oui j'avais pensé à la déconnexion brutale en cas de taille farfelue ^^
    J'ai aussi bien sûr le type de message envoyé !

    Pour le bug de "décalage", je pensais plutôt à une erreur de ma part :p

    Et évidemment, j'ai déjà complètement encapsulé ma partie "bas niveau"

  6. #6
    Invité
    Invité(e)
    Par défaut
    autre question bête,
    c'est quoi les receive/sendBufferSize des Socket ET DatagramSocket ?
    quand j'utilise UDP, j'ai remarqué que certains paquets trop gros n'étaient tout simplement pas transmis ! plus de 8 ko je crois.
    C'est bien 65000 octets la limite théorique d'un paquet UDP ? (approximativement)

Discussions similaires

  1. Protocoles TCP et UDP
    Par gabgab dans le forum Protocoles
    Réponses: 6
    Dernier message: 10/01/2014, 17h38
  2. Réponses: 1
    Dernier message: 09/10/2013, 21h41
  3. Création d'un protocole : TCP ou UDP ?
    Par ram-0000 dans le forum Contribuez
    Réponses: 2
    Dernier message: 24/04/2013, 09h00
  4. Communication TSX Premium -> TCP ou UDP
    Par abyssetique dans le forum Automation
    Réponses: 2
    Dernier message: 28/10/2011, 21h55
  5. développement d'un protocole de communication
    Par olymat dans le forum Développement
    Réponses: 5
    Dernier message: 09/09/2005, 09h23

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