Multiples question sur les sockets en Java

Différencier les types ? Une longueur maximal ? Timeout ? Etc.

a marqué ce sujet comme résolu.

Bonjour,

je me suis récemment attaqué aux réseaux (serveur - client) en Java. N'ayant pas trouver de tutoriels concret, j'ai cherché à pas mal d'endroit sur le Net.

Mais plusieurs points m’interroge tout de même.

  • Quel est le timeout idéale ? (J'ai vu à des endroits sur internet qu'il mettait jusqu'à 10 seconds, mais quand je dis à mon serveur STOP, j'aimerais qu'il le fasse le plus rapidement sans forcément attendre 10 secondes)
  • Quelle peut-être la longueur de texte que je peux mettre dans un socket ? Car j'ai essayer avec un grand texte, il n'est jamais parvenu sur le serveur.
  • Y a t'il un moyen de séparer les sockets, c'est à dire par exemple un socket pour le chat, un pour les commandes, un pour la position des joueurs et j'en passe. (Savoir s'il y a un autre moyen que celui que je me suis imaginer avec des regex traitant des textes.
  • sur mon client, comment puis-je fermer correctement mon socket ? Car si je fais un client.close(), j'ai une erreur car il est en train d'écouter s'il y a une entrée.
  • Quand mon client quitte le serveur, j'ai une exception de type EOFExeption, est-ce normal ?
  • Comment fait-on pour gérer le TCP / UDP ?
  • En UDP, pour la position de joueur par exemple, combien de données et quelle longueur peut-on envoyer par seconde pour ne pas tout surcharger le réseaux ? (Et également le serveur ?) j'ai de la peine à m'imaginer comment gérer les connexions à petit débit, qu'est-ce qu'il en résultera.

C'est à peut près toutes les questions que j'ai pour le moment, si une gentil âme à un petit moment pour m'éclaircir tout cela, c'est avec grand plaisir.

Merci, WinXaito

Bonsoir !

  • Quel est le timeout idéale ? (J'ai vu à des endroits sur internet qu'il mettait jusqu'à 10 seconds, mais quand je dis à mon serveur STOP, j'aimerais qu'il le fasse le plus rapidement sans forcément attendre 10 secondes)

Tu peux toujours effectuer les opérations bloquantes dans un thread séparé, un appel à close() sur le socket tuera de toute façon l'action en cours. Pour le timeout, je ne m'y connais pas, mais à priori ça dépend énormément de l'application et du nombre de clients (pas la même chose pour une utilisation smartphone, ni pour un jeu comme WoW).

  • Quelle peut-être la longueur de texte que je peux mettre dans un socket ? Car j'ai essayer avec un grand texte, il n'est jamais parvenu sur le serveur.

TCP ou UDP ? A priori il n'y a pas de limite, mais le tampon mémoire qui reçoit derrière doit être suffisamment grand.

  • Y a t'il un moyen de séparer les sockets, c'est à dire par exemple un socket pour le chat, un pour les commandes, un pour la position des joueurs et j'en passe. (Savoir s'il y a un autre moyen que celui que je me suis imaginer avec des regex traitant des textes.

Tu peux séparer les applications en changeant de port, mais pourquoi ne pas simplement identifier les types de paquets en envoyant un identifiant entier/texte au tout début du message ?

  • sur mon client, comment puis-je fermer correctement mon socket ? Car si je fais un client.close(), j'ai une erreur car il est en train d'écouter s'il y a une entrée.

Une erreur sur client.close() ? Quelle est l'erreur exactement ?

  • Quand mon client quitte le serveur, j'ai une exception de type EOFExeption, est-ce normal ?

A tout hasard, tu ne vérifies pas l'état du socket avant de lire, ce qui déclenche des exceptions dans cette classe : https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html

  • Comment fait-on pour gérer le TCP / UDP ?

Par défaut, c'est TCP en java. Pour UDP il faut voir du coté de http://www.liafa.jussieu.fr/~sighirea/cours/reseauxM/java.udp.html

  • En UDP, pour la position de joueur par exemple, combien de données et quelle longueur peut-on envoyer par seconde pour ne pas tout surcharger le réseaux ? (Et également le serveur ?) j'ai de la peine à m'imaginer comment gérer les connexions à petit débit, qu'est-ce qu'il en résultera.

Je laisse la réponse à un autre, mais valve fournit pas mal de données là dessus sur le devsite. ;)

Quel est le timeout idéale ? (J'ai vu à des endroits sur internet qu'il mettait jusqu'à 10 seconds, mais quand je dis à mon serveur STOP, j'aimerais qu'il le fasse le plus rapidement sans forcément attendre 10 secondes)

Ca dépend de ce que tu entends par timeout. LE plus souvent on s'assure que la connexion est toujours active à l'aide de messages de ping / nop / heartbit prévus par le protocole, si la connexion doit durer dans le temps.

Ca dépend aussi de l'état de la communication et du type de service: virer un mec qui n'a jamais rien envoyé après 3s seulement, ça se fait bien; virer un mec qui est en train de transférer 100 Go parce que pendant 3s il n'a rien envoyé alors que ça faisait 2h qu'il était plutôt stable, c'est très moyen.

Quelle peut-être la longueur de texte que je peux mettre dans un socket ? Car j'ai essayer avec un grand texte, il n'est jamais parvenu sur le serveur.

Dans le cadre de TCP, ça peut être aussi petit ou aussi grand que tu le souhaites. C'est l'OS qui va s'occuper d'envoyer des paquets de taille raisonnable qui passeront bien sur le réseau. Les algorithmes internes de TCP sont conçus pour envoyer des paquets dès que c'est nécessaire, et uniquement quand c'est nécessaire, de façon généralement optimum, sans paramétrage, autant pour la vitesse que le débit, sans que tu n'aies à t'en soucier. Du point de vue utilisateur, tu te sers juste d'un flux continu de données. Si tu n'as jamais rien reçu, assure-toi de bien faire un flush sur le flux de sortie; sinon rien ne sera jamais envoyé.

Du côté de UDP par contre c'est différent. On recommande le plus souvent de ne pas dépasser 1400 octets par paquet, pour être sûr qu'il ne sera jamais fragmenté par les protocoles de couche 2-3 courants. En théorie on peut aller jusqu'à 65535 octets par paquet, mais la fragmentation peut poser des problèmes sur les noeuds intermédiaires (noeuds peering, routeurs, firewalls, etc.) et c'est pour ça qu'on préfère l'éviter.

Y a t'il un moyen de séparer les sockets, c'est à dire par exemple un socket pour le chat, un pour les commandes, un pour la position des joueurs et j'en passe. (Savoir s'il y a un autre moyen que celui que je me suis imaginer avec des regex traitant des textes.

C'est possible, mais en général on évite d'avoir à gérer 36 connexions. En gérer une seule correctement est déjà assez vite compliqué. Habituellement on préfère plutôt indiquer la nature de chaque message en début de celui-ci.

Inspire-toi des protocoles existants pour comprendre: Dans la plupart des protocoles, chaque message commence par un mot commande, p.ex. GET, POST, etc. pour HTTP; RETR, DELE, etc. pour POP3; HELO, FROM, etc. pour SMTP, et ainsi de suite. De même les réponses commencent très souvent par un numéro de code pour qu'on sache tout de suite ce qui se passe: 100 c'est en cours, 200 ça a marché, 400 le client a fait une erreur, 500 le serveur a planté, etc. C'est commun à HTTP, FTP, SMTP, IRC, et beaucoup d'autres.

Si tu as opté pour un format binaire, les mots commandes sont remplacés par des opcodes (operation codes), mais c'est le même principe. Attention au fait que débugger un message binaire est probablement plus compliqué qu'un message textuel.

sur mon client, comment puis-je fermer correctement mon socket ? Car si je fais un client.close(), j'ai une erreur car il est en train d'écouter s'il y a une entrée.

En mode synchrone, tu ne peux pas éviter la SocketException. IL faut juste l'ignorer.

Quand mon client quitte le serveur, j'ai une exception de type EOFExeption, est-ce normal ?

Ca peut, oui; l'EOFException signifie souvent que la connexion a été interrompue en plein milieu d'un message. C'est pas forcément grave.

En UDP, pour la position de joueur par exemple, combien de données et quelle longueur peut-on envoyer par seconde pour ne pas tout surcharger le réseaux ? (Et également le serveur ?) j'ai de la peine à m'imaginer comment gérer les connexions à petit débit, qu'est-ce qu'il en résultera.

C'est extrêmement variable selon la qualité du réseau d'un bout à l'autre. IL faut faire des essais et garder une bonne marge de sécurité pour être sûr de bien supporter les petites connexions.

Ce qu'il y a d'important à retenir avec UDP c'est que les paquets perdus ne sont pas automatiquement réexpédiés. En réalité c'est assez facile à voir si tu en envoies trop en quantité ou trop rapidement, le rapport paquets envoyés / paquets perdus chute brutalement, et ne remonte que quand tu diminues la cadance. Mais une fois le constat fait, il ne faut pas seulement s'arranger pour rester pile en-dessous de la zone critique. Sinon à la moindre surcharge ponctuelle tu vas souffrir, et tous les gens qui n'ont pas une aussi bonne connexion que toi vont aussi souffrir.

+0 -0

Bonsoir,

Je viens ajouter mon grain de sel :

Quel est le timeout idéale ?

Généralement il n'y a pas de timeout idéal, mettre en place un timeout dépend d'un besoin spécifique.

sur mon client, comment puis-je fermer correctement mon socket ? Car si je fais un client.close(), j'ai une erreur car il est en train d'écouter s'il y a une entrée.

Quelque chose me dit que tu fais gère un objet socket via plusieurs threads (un qui reçoit des données, un autre qui tente de fermer la connexion pendant l'activité), le problème peut venir de là.

TCP ou UDP ? A priori il n'y a pas de limite

Pour UDP si, un paquet peut contenir jusqu'à 65535 octets (tu dois y soustraire les options en en-tête). Il ne faut pas non-plus négliger les contraintes réseaux que cite QuentinC.

Par défaut, c'est TCP en java.

Il n'y a pas de protocole par défaut en Java, ce dernier met disposition des librairies pour réaliser des connexions TCP ou UDP. Je pense que tu as voulu dire que TCP était plus utilisé que UDP :p

+1 -0

sur mon client, comment puis-je fermer correctement mon socket ? Car si je fais un client.close(), j'ai une erreur car il est en train d'écouter s'il y a une entrée.

Quelque chose me dit que tu fais gère un objet socket via plusieurs threads (un qui reçoit des données, un autre qui tente de fermer la connexion pendant l'activité), le problème peut venir de là.

Effectivement c'est fort possible que je ferme la connexion via le mauvais thread.

Et merci pour le reste :D

Il n'y a pas de protocole par défaut en Java, ce dernier met disposition des librairies pour réaliser des connexions TCP ou UDP. Je pense que tu as voulu dire que TCP était plus utilisé que UDP :p

Gugelhupf

Effectivement, le par défaut est très maladroit ! Non, WinXaito semblait utiliser java.net.socket, et je voulais simplement dire que c'était TCP qui était utilisé à cet endroit, en donnant la doc pour Datagram. :p Après la doc indique que les sockets peuvent être utilisé (avec un constructeur obsolète maintenant) pour faire de l'UDP, donc je n'étais pas non plus totalement dans le rouge ! :-°

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte