2017-10-14 17 views
0

Je travaille sur un projet qui nécessite une communication à faible latence entre un serveur et une application cliente. Les deux fonctionnent sur mon ordinateur donc il est connecté à localhost.java: Flux d'E/S dans le socket client/serveur causant un retard aléatoire de 300ms

Le transfert de données via DataInputStream et DataOutputStream et la connexion socket fonctionne correctement, et 99% du temps, le ping est mesurée 0ms ou 1ms, parfois la communication mais est en retard au hasard par 300ms.

Les applications normales telles que les jeux en réseau fonctionnent bien sans aucune "lagspikes", donc je suis sûr que ce n'est pas un problème avec mon ordinateur.

Je trouve très suspect que le retard est toujours exactement 300ms quand il se produit et 0ms ou 1ms quand il ne se produit pas, alors il y a quelque chose qui se passe, mais je ne peux pas savoir quoi.

Je me suis connecté avec horodatages jusqu'à déterminer ce qui se passe à la fois au serveur et le client à l'un des

in.read(); 

avec en étant le DataInputStream si im en supposant que le délai ne soit pas directement dans mon code.

Quelqu'un peut-il m'expliquer, qu'en Java, le flux d'E/S ou les sockets provoque un décalage de 300ms et comment le résoudre? La seule chose que j'ai changé pour le serveur/client est

socket.setPerformancePreferences(0, 1, 0); 

mais il n'a pas changé une chose.

Mon code est un peu gros, mais la structure générale de la partie pertinente du serveur et l'application client ressemble à:

while(still_alive) { 
    out.writeInt(data1); 
    out.writeInt(data2); 
    out.writeDouble(data3); 
    data1 = in.readInt(); 
    data2 = in.readInt(); 
    data3 = in.readDouble(); 
    DoSomethingWithData(data1, data2, data3); 
} 

Merci à l'avance!

Kaisky

+0

Avez-vous essayé d'obtenir des statistiques sur l'exécution d'une application? L'une des idées que j'ai est l'événement Stop The World qui peut se produire pendant le GC. Voici une référence sur la façon de surveiller le GC: https://www.cubrid.org/blog/how-to-monitor-java-garbage-collection –

+0

Je l'ai essayé maintenant mais ne semble pas causer le problème - aussi essayé d'exécuter System.gc() manuellement au début de chaque trame réseau sur le serveur et le client - il augmente le ping mesurée par ~ 6-8 ms par défaut mais in.read() bloque encore pendant 300ms, donc il mesure 306-308ms – Kaisky

Répondre

0

J'ai trouvé la solution!

Il semble que DataInputStream et DataOutputStream ne conviennent pas pour le réseau à faible latence, mais vous devez utiliser BufferedInputStream et BufferedOutputStream à la place. Il est un peu plus difficile à utiliser car chaque entrée est en octets, donc vous devez traduire tout int, double et String en tableaux d'octets et les traduire, donc j'ai pris un peu de temps pour le faire mais maintenant ça fonctionne parfaitement sans tout retard.