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 :

Optimisation d'un Serveur Socket


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Tigrounette
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 132
    Par défaut Optimisation d'un Serveur Socket
    Bonjour à tous,

    J'aimerais optimiser un serveur Java utilisant des sockets. J'ai commencé à le réaliser il y a longtemps à partir d'un tutorial, car java et moi ça faisait 2. J'ai entièrement tout recodé sauf quelques parties : la partie reception de donnée et la partie envoie de donnée. Mais en utilisant un profiler, j'ai pu voir que ces parties étaient les plus critiques.

    Même si je trouve ça logique, j'aimerais être sure que ces parties soient bien optimisées, voilà comment ça se passe :

    Pour la partie reception de donnée, chaque client déclenche l'ouverture d'un nouveau thread avec ceci dans la méthode run() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void run() {
            String Message = "";
            char charCur[] = new char[1];
            while (_in.read(charCur, 0, 1) != -1) {
                if (charCur[0] != '\u0000') {
                    Message += charCur[0];
                } else {
                    // Message reçu, suite du traitement
                    Message = "";
                }
            }
    }
    _in est déclaré plus tôt dans le constructeur de la classe par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _in = new BufferedReader(new InputStreamReader(_s.getInputStream()));
    où _s correspond à l'objet Socket du client.

    Pour l'envoie de donnée depuis le serveur ça fait comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    _out.print(StringMessageDeRetour + "\u0000");
    _out.flush();
    où _out est déclaré au même endroit que _in (dans chque thread client) de la façcon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _out = new PrintWriter(_s.getOutputStream());
    Voilà, pensez vous qu'il est possible de faire mieux (rapidité et/ou ressources utilisées) ? Je commence à connaitre JAVA, mais je n'ai aucune connaissance théorique pointue, ce qui m'empêche d'optimiser ce genre de chose.

    Autre chose, je ne sais pas trop où placer mes méthodes d'envoie de donnée depuis le serveur. Au départ, elles étaient dans les threads de chaque client, mais en faisant des test de surcharge, j'ai eu droit à quelques erreurs. Maintenant je lance un thread à part au lancement du serveur qui s'occupe exclusivement de l'envoie de donnée, je n'ai plus d'erreur mais je sais absolument pas si j'ai bien fait.

    Voila, merci d'avance pour l'aide

  2. #2
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Coté entrée, je pense que cette instruction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Message += charCur[0];
    ... doit bouffer pas mal de ressources ! À première vue il faut préférer l'usage d'un StringBuffer ou StringBuilder.

    Coté sortie, je ne vois pas grand chose.

    Si tu as de l'audace, considère la refonte à partir du ServerSocketChannel.

    Tu souhaites optimiser en vitesse et/ou en mémoire ?

  3. #3
    Membre expérimenté Avatar de jibbi
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 165
    Par défaut


    Pour transférer des fichiers assez rapidement il y a un exemple client/serveur
    ici:
    http://www.developpez.net/forums/sho...33&postcount=8


    Mais il semble que tu veux transmettre des String. Si c'est le cas , il y une facon très "élégante" de le faire. Pas très rapide mais, pour un chat c'est parfait.

    Peut-on voir le code coté serveur ?

  4. #4
    Membre confirmé Avatar de Tigrounette
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 132
    Par défaut
    En fait, je cherche avant tout la rapidité d'execution peut importe le coût en mémoire (tout en restant raisonnable), c'est pour un jeu multijoueur en temps réel.

    Là j'ai fait les modifications suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public void run() {
            StringBuilder Message = new StringBuilder(100);
            char charCur[] = new char[1];
            while (_in.read(charCur, 0, 1) != -1) {
                char C = charCur[0];
                if (C != '\u0000') {
                    Message.append(C);
                } else {
                    // Message reçu, suite du traitement
     
                    // Reset de Message
                    Message = new StringBuilder(100);
                }
            }
    }
    Pour un texte de 7 ko je passe de 94~125 millisecondes à 0~10 millisecondes de traitement (très souvent 0, alors que le texte fait plus de 100 caractère et que les clients envéront à 99% des messages inférieurs à 100 caractères, donc ça devrait aller encore plus vite!), si c'est pas de l'optimisation ça ! Merci pour le conseil ! Je vais d'ailleur m'empresser de remplacer toute les concaténations de String de mon programme

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Tigrounette
    Pour un texte de 7 ko je passe de 94~125 millisecondes à 0~10 millisecondes de traitement (très souvent 0, alors que le texte fait plus de 100 caractère et que les clients envéront à 99% des messages inférieurs à 100 caractères, donc ça devrait aller encore plus vite!), si c'est pas de l'optimisation ça !
    En fait il faut à tout prix éviter d'utiliser la concaténation de String avec + dans une boucle, car en réalité cela crée un StringBuffer/StringBuilder et une nouvelle String à chaque itération (voir la FAQ : Comment concatener des chaînes de caractères ?)

    Dans ton cas c'est assez peu pénalisant car la quantité de donnée est vraiment infime, mais dans le cas de données un peu plus importe cela peut être catastrophique (du style pour lire 500Ko de donnée ont peut arriver à allouer successivement l'équivalent de 2Go de mémoire...)


    Citation Envoyé par Tigrounette
    Je vais d'ailleur m'empresser de remplacer toute les concaténations de String de mon programme
    Mais ce n'est pas pour autant qu'il faut toutes les remplacer !!!
    Lorsque la concaténation tient sur une seule ligne (et pas dans une boucle), il est préférable de la conserver...

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String str = "Ma chaine " + maValeur + " encore une chaine " + uneAutreValeur;
    En effet le compilateur compilera cela en utilisant un StringBuffer/StringBuilder de toute manière, et cela permet de garder un code plus lisible

    a++

Discussions similaires

  1. [FLASH MX2004] [XMLSocket] Problème avec serveur socket php
    Par cocodunombril dans le forum Flash
    Réponses: 4
    Dernier message: 03/04/2009, 02h10
  2. Compiler du java en natif & Optimisation serveur socket
    Par Skreo dans le forum API standards et tierces
    Réponses: 32
    Dernier message: 09/07/2006, 16h31
  3. problème de serveur socket
    Par hiul dragonfel dans le forum MFC
    Réponses: 3
    Dernier message: 01/06/2006, 11h56
  4. Question client-serveur socket
    Par Lex99 dans le forum Développement
    Réponses: 3
    Dernier message: 07/02/2006, 09h01

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