Question

Je simple configuration client / serveur. Le serveur est en C et le client qui interroge le serveur est Java.

Mon problème est que, quand j'envoie des données gourmandes en bande passante sur la connexion, tels que les images vidéo, il tombe jusqu'à la moitié des paquets. Je fais en sorte que fragment correctement les paquets UDP sur le côté serveur (UDP a une longueur de charge utile maximale de 2 ^ 16). Je vérifié que le serveur envoie des paquets (printf le résultat de sendto ()). Mais java ne semble pas obtenir la moitié des données.

En outre, quand je passe à TCP, toutes les images vidéo passer à travers, mais le temps d'attente commence à se former, en ajoutant délai de plusieurs secondes après quelques secondes de l'exécution.

Y at-il évident que je suis absent? Je juste ne peux pas comprendre cela.

Était-ce utile?

La solution

Obtenez un outil de réseau comme Wireshark afin que vous puissiez voir ce qui se passe sur le fil.

UDP ne fait aucune tentative de retransmission, donc si un paquet est abandonné quelque part, il appartient au programme pour faire face à la perte. TCP va travailler dur pour fournir tous les paquets au programme afin, jeter dups et en demandant des paquets perdus sur lui-même. Si vous voyez une latence élevée, je parie que vous verrez beaucoup de perte de paquets TCP et, qui apparaissent comme des retransmissions à partir du serveur. Si vous ne voyez pas retransmissions TCP, peut-être le client gère pas les données assez vite pour suivre.

Autres conseils

Tout protocole d'application UDP inévitablement à base sensibles à la perte de paquets, et réordonner les doublons (dans certaines circonstances). Le « U » dans UDP pourrait signifie « non fiable » comme dans Unreliable Datagram Protocol. (OK, il signifie vraiment « User » ... mais il est certainement une bonne façon de se rappeler les caractéristiques de UDP).

pertes de paquets UDP se produisent généralement parce que votre trafic dépasse la capacité tampon d'un ou plusieurs des « sauts » entre le serveur et le client. Lorsque cela se produit, les paquets sont abandonnés ... et puisque vous utilisez UDP, il n'y a pas de notification protocole au niveau du transport que cela se produit.

Si vous utilisez UDP dans une application, l'application doit tenir compte de la nature peu fiable UDP, la mise en œuvre de ses propres mécanismes pour traiter des paquets abandonnés et hors ordre et pour faire son propre contrôle de flux. (Une application qui explosions des paquets UDP sans penser à l'effet que cela peut avoir sur un réseau déjà surchargé est un mauvais citoyen réseau ).

(Dans le cas TCP, les paquets sont probablement chuté aussi, mais TCP est la détection et renvoyer les paquets perdus, et le mécanisme de contrôle de flux TCP est kicking pour ralentir la vitesse de transmission des données. Le résultat net est " latence ».)

EDIT - basé sur l'observation de l'OP, la cause de son problème était que le client n'a pas été « à l'écoute » pendant une période, ce qui provoque les paquets (probablement) être abandonné par le système d'exploitation du client. La façon d'aborder c'est à:

  1. utiliser un fil Java dédié juste lit les paquets et les files d'attente pour le traitement, et

  2. augmenter la taille de la file d'attente de paquet de noyau pour la prise.

Mais même lorsque vous prenez ces mesures, vous pouvez toujours obtenir des paquets abandonnés. Par exemple, si la machine est en surcharge, l'application ne peut pas obtenir l'exécution tranches de temps assez souvent pour lire et la file d'attente tous les paquets avant que le noyau doit les laisser tomber.

EDIT 2 - Il y a un débat quant à savoir si UDP est susceptible de doublons. Il est certainement vrai que UDP n'a pas la détection ou la prévention de la double innée. Mais il est vrai aussi que le tissu de routage de paquets IP qui est l'Internet est peu susceptible de reproduire spontanément des paquets. Donc, les doublons, si elles se produisent, sont susceptibles de se produire parce que l'expéditeur a décidé de renvoyer un paquet UDP. Ainsi, à mon esprit alors que UDP est sensible aux problèmes avec les doublons, il ne les fait pas en soi ... à moins d'un bogue dans la pile de protocole OS ou dans le tissu IP.

Bien que UDP prend en charge les paquets jusqu'à 65535 octets ( dont l'en-tête UDP, qui est de 8 octets - mais voir note 1), les transports sous-jacents entre vous et la destination ne prennent pas en charge les paquets IP c'est long. Par exemple, les trames Ethernet ont une taille maximale de 1500 octets - prenant en tête de compte pour l'IP et les en-têtes UDP, cela signifie que tout paquet UDP avec une longueur de charge utile de données de plus d'environ 1450 est susceptible d'être fragmenté en datagrammes IP multiples.

Une taille maximale paquet UDP va être fragmenté en au moins 45 datagrammes IP séparés - et le cas échéant un de ces fragments est perdu, tout le paquet UDP est perdu. Si votre taux de perte de paquets sous-jacente est de 1%, votre application voir un taux de perte d'environ 36%!

Si vous voulez voir moins de paquets perdus, ne pas envoyer d'énormes paquets - limiter vos données dans chaque paquet à environ 1400 octets (ou même faire votre propre « sentier découverte MTU » pour déterminer la taille maximale que vous pouvez envoyer en toute sécurité sans fragmentation).


  1. Bien sûr, UDP est également soumis aux limites de la propriété intellectuelle et datagrammes IP ont une taille maximale de 65535, y compris l'en-tête IP. L'en-tête IP est comprise dans la taille de 20 à 60 octets, de sorte que la quantité maximale de données d'application transportable dans un paquet UDP peut être aussi faible que 65.467.

Le problème est peut-être à voir avec votre tampon de transmission se remplir dans votre UDPSocket. Seulement envoyer la quantité d'octets en une seule fois indiqué par UDPSocket.getSendBufferSize(). Utilisez setSendBufferSize(int size) pour augmenter cette valeur.

  

Si #send () est utilisé pour envoyer un   DatagramPacket qui est plus grande que la   réglage SO_SNDBUF il est alors   la mise en œuvre spécifique si le paquet   est envoyé ou mis au rebut.

IP prend en charge paquets jusqu'à 65535 octets dont un 20 octets en-tête de paquet IP. UDP supports datagrammes jusqu'à 65507 octets, plus l'en-tête IP de 20 octets et 8 octets en-tête UDP. Cependant, le réseau MTU est la limite pratique, et ne pas oublier que cela inclut non seulement ces 28 octets, mais aussi l'en-tête de trame Ethernet. real limite pratique pour UDP est le MTU non fragmenté minimum de 576 octets moins tous les frais généraux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top