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 :

[Socket] optimiser les paramètres de connexion


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut [Socket] accélerer le débit
    bonjour,

    j'ouvre un port puis j'envoie un tableau sur ce port. Tout se passe bien je reçois exactement ce que je veux. Le problème est que la durée d'envoi des données est trop longue. Elle est de 300ms. On m'impose d'envoyer ces données en moins de 30ms.

    Comment je peux accélérer le débit ? J'utilise un DataOuptuStream pour envoyer mon tableau :

    Voici mon code : (j'ai volontairement enlevé les try{}catch{})
    Le code après la méthode accept dure 300ms.
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    socketServerSender=new ServerSocket(4000);
     
    socketServerSender.setSoTimeout(2000);
    socketSender=this.socketServerSender.accept();
     
     
    out=socketSender.getOutputStream();
    dos=new DataOutputStream(out);
     
    dos.writeInt(255);
    dos.flush();
    out.flush();
     
    int n, m, o;
    int i, j, k;
    n = tabInt.length;		//9(objets)
    m = tabInt[0].length;	//50(lignes)
    o = tabInt[0][0].length;	//20(colonnes)
     
     
    for (i=0;i<n;i++)
    {
    	for (j=0;j<m;j++)
    	{
    		for (k=0;k<o;k++)
    		{
    			dos.writeInt(tabInt[i][j][k]);
    		}
    	}
    }
     
    dos.flush();
    out.flush();
    J'ai essayé de remplacer mon tableau 3D par un tableau 1D, même chose j'ai un temps d'envoi de 300ms environ.


    [edit]
    Petite précision :
    ce code se trouve dans un thread. Est-ce que ça peut expliquer la lenteur d'exécution ?
    [/edit]

  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
    D'abord, comment vérifies-tu les 30ms ?

    Ensuite, je suis un peu étonné que tu utilises un DataOutpurStream, un flux assez évolué, qui fait des traitements sur les données, risque de perte de temps j'imagine ; pourquoi n'utilises-tu pas un BufferedOutputStream, ou même directement l'OutputStream de la socket ?

    Ensuite, peut être aussi examiner les possibilités de nio, mais j'ai jamais su si c'était vraiment plus rapide, en tous cas c'est prévu pour.

  3. #3
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par gifffftane Voir le message
    D'abord, comment vérifies-tu les 30ms ?
    sur le programme client. Je mesure le temps avant et après exécution du programme.

    Petite remarque importante : le programme client n'est pas en Java mais en matlab (la fonction pnet pour être précis).

    Citation Envoyé par gifffftane Voir le message
    Ensuite, je suis un peu étonné que tu utilises un DataOutpurStream, un flux assez évolué, qui fait des traitements sur les données, risque de perte de temps j'imagine ; pourquoi n'utilises-tu pas un BufferedOutputStream, ou même directement l'OutputStream de la socket ?
    Disons que j'ai pris le DataOutputStream car c'est à ma connaissance le seul objet capable d'envoyer des int32.
    Quant au BufferedOutputStream j'avoue que je ne sais pas vraiment m'en servir J'ai essayé d'envoyer des informations via cet objet je recueillais n'importe quoi à l'arrivée (sans doute parce j'ai dû mal configurer pnet).

    Citation Envoyé par gifffftane Voir le message
    Ensuite, peut être aussi examiner les possibilités de nio, mais j'ai jamais su si c'était vraiment plus rapide, en tous cas c'est prévu pour.
    tu penses au IntBuffer ? Mais je ne vois pas comment l'associer au OutputStream de mon socket

  4. #4
    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
    Citation Envoyé par Auteur Voir le message
    sur le programme client. Je mesure le temps avant et après exécution du programme.

    Petite remarque importante : le programme client n'est pas en Java mais en matlab (la fonction pnet pour être précis).
    Donc à ce que je comprends de la doc, le temps compté est non seulement celui du transfert, mais de plus il y a dedans le temps d'ouverture de la connexion socket, non ?

  5. #5
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par gifffftane Voir le message
    Donc à ce que je comprends de la doc, le temps compté est non seulement celui du transfert, mais de plus il y a dedans le temps d'ouverture de la connexion socket, non ?
    Tout à fait.

    Du côté matlab : j'ouvre le port, je reçois les données puis je ferme le port. Pour ce programme Matlab, je n'ai pas le choix, je dois procéder ainsi. Donc du côté Java je dois me plier à cette contrainte.

    Du côté Java : j'attends l'ouverture du port, dès qu'il est ouvert j'envoie mes données. Donc en Java, je suis obligé de faire un thread dans lequel je mets une boucle avec la méthode accept(). Dès que la connexion est établie, un flag passe à true, je sors de la boucle et j'envoie les données.


    Quand je vois mon programme Java, je constate qu'il n'est pas très optimisé :red: :red:

  6. #6
    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
    Pour en revenir à nio, tu as un exemple de serveur dans la doc du jdk à NIO Examples :TimeServer renvoie l'heure - ce n'est pas très différent de tes entiers je suppose - de façon nio-teligente.

  7. #7
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut [Socket] optimiser les paramètres de connexion
    bonjour,

    j'ouvre un port de cette manière :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    socketServerSender=new ServerSocket(4000);
     
    socketServerSender.setSoTimeout(2000);
    socketSender=this.socketServerSender.accept();
     
    // envoi des données
    out=socketSender.getOutputStream();
    dos=new DataOutputStream(out);
     
    dos.writeInt(255);
    dos.flush();
    out.flush();
     
    int n, m, o;
    int i, j, k;
    n = tabInt.length;		//9(objets)
    m = tabInt[0].length;	//50(lignes)
    o = tabInt[0][0].length;	//20(colonnes)
     
     
    for (i=0;i<n;i++)
    {
    	for (j=0;j<m;j++)
    	{
    		for (k=0;k<o;k++)
    		{
    			dos.writeInt(tabInt[i][j][k]);
    		}
    	}
    }
     
    dos.flush();
    out.flush();
     
    //.... etc.

    Mon souci est que le débit est un peu lent : 300ms pour tout envoyer. Je voudrais envoyer les données en 30ms. De plus la méthode accept étant bloquante, je suis obligé de placer ce code dans un thread.

    Les 300ms sont mesurés sur le poste client : le programme client ouvre le port, reçoit les données, puis ferme le port.

    Mais visiblement un DataOuputStream n'est pas l'idéal pour ça il faudrait que j'utilise l'API nio plutôt que io.


    A priori il faudrait que je passe par un SocketChannel pour envoyer mes données plus rapidement. Du coup je me demande :
    • est-ce que je dois le configurer comme bloquant ou non bloquant ? Sur ce point je n'ai pas très bien compris la différence entre bloquant et non bloquant.
    • est-ce je peux améliorer le débit en modifiant les paramètres de connexion de mon socket ? Je pensais à la méthode setTrafficClass et fermer le flux d'entrée (shutdownInput) car par ce port je ne reçois aucune donnée.

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    T'as essayé de passer par un BufferedOutputStream ?

  9. #9
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Oui, mais les données reçues sont visiblement mal interprétées par le programme client. Sans douter une mauvaise configuration du programme client... Donc je réessayerai.


    En fait, j'avais choisi le DataOuputStream car je peux envoyer directement des entiers 32 bits, tandis que les autre types d'objets (comme le BufferedOutputStream) n'envoient que des Bytes ou des Char.
    Ce qui pose quelques soucis pour réceptionner les données (le programme client est sous Matlab, pas en java).


    Pour le BufferedOutputStream tu peux me donner un exemple d'utilisation ? Comment ferais-tu pour envoyer des entiers 32 bits en utilisant un tableau de Bytes (car visiblement le BufferedOutputStream ne gère que ce format) ?

  10. #10
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Ben d'après la Javadoc, le BufferedOutputStream a les méthodes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    write(byte[] b, int off, int len)
    Writes len bytes from the specified byte array starting at offset off to this buffered output stream.
    Writes the specified byte to this buffered output stream.

    Il suffit d'encapsuler ton DataOutputStream dans le BufferedOutputStream.

    A tester.

  11. #11
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    Citation Envoyé par fr1man Voir le message

    Il suffit d'encapsuler ton DataOutputStream dans le BufferedOutputStream.
    Certains concepts m'échappent encore en Java. Peux-tu me dire comment tu ferais ? Pour moi les types sont incompatibles....


    Tu ne sais pas si en jouant sur ces paramètres de connexion je peux améliorer la vitesse de transfert des données (cf. mon 1er message) ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 01/12/2008, 09h57
  2. Externaliser les paramètres de connexion à la base ?
    Par Bobsinglar dans le forum Struts 2
    Réponses: 4
    Dernier message: 30/11/2007, 11h03
  3. [D7 - ADO]Tester les paramètres de connexion
    Par portu dans le forum Bases de données
    Réponses: 3
    Dernier message: 17/04/2007, 19h29
  4. Optimiser les paramètres MySQL - appel aux experts
    Par SuperCed dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 04/12/2006, 12h26
  5. Cacher les paramètres de connexion à la BD
    Par Invité dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 12/10/2006, 17h04

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