Socket Server übertragung wird immer langsamer

pcProfie

Aktives Mitglied
hallo ich habe ein programm erstellt bei dem der client dem server 256kb schickt und dieser die 256kb wieder zurückschickt. das zeit für das ganze wird gemessen, wird aber bei jedem durchlauf um ca. 2-3 sekunden länger! woran kann das liegen? muss ich irgendetwas leeren oder so? es ist wichtig dass die zeiten immer ungefähr gleich sind, ich werde ein paar tests machen und von den ergebnissen den durchschnitt nehmen, aber die zeiten sollten mal mehr, mal weniger werden und nicht wachsen! was habe ich nicht bedacht?

interne klasse aus hauptklasse server: @clienten ist eine arraylist mit "serverclient". serverclient ist eine hilfsklasse die nur ein socket als datenfeld hat und unteranderem read und write als methoden
Java:
private  class ReadData extends Thread {

        @Override
        public void run() {
            while (true) {
                for (int i = 0; i < clienten.size(); i++) {
                    try {
                        String t = clienten.get(i).read();
                        if(t == null) throw new Exception();
                        clienten.get(i).write(t);
                    } catch (Exception se) {
                        System.out.println("Client "+clienten.get(i).getSocket().getInetAddress() + " left");
                        try {
                            clienten.get(i).close();
                        } catch (Exception e) {
                            e.printStackTrace(); 
                        }
                        clienten.remove(i);
                        i--;
                    }
                }
            }
        }
    }

aus serverclient:
Java:
    public void write(String nachricht) throws IOException {
        if(nachricht != null) {
            PrintWriter printWriter = new PrintWriter(s.getOutputStream());
            printWriter.println(nachricht);
            printWriter.flush();
        } else {
            System.err.println("Server: Ich schreibe nicht null!");
        }
    }

    public  String read() throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String t = in.readLine();
        System.out.println(s.getInetAddress() + " sent: "+t);
        return t;
    }

aus clientenklasse:
Java:
    public void write(String nachricht) throws IOException {
        if(nachricht != null) {
            PrintWriter printWriter = new PrintWriter(server.getOutputStream());
            printWriter.println(nachricht + " ");
            printWriter.flush();
        } else {
            System.err.println("Client: Ich schreibe nicht null!");
        }
    }

    public String read() throws Exception {
        BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
        String t = in.readLine();
        //System.out.println("Server sent: "+t);
        return t;
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() == senden) {
            try {
                long time = System.currentTimeMillis();
                write(eingabe.getText());
                while(read() == null);
                time = System.currentTimeMillis() - time;
                zeit.setText("Letzte Zeit: " + time);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }  else if(ae.getSource() == send1) {
            int mb = 256 * 1024;
            StringBuilder sb = new StringBuilder(mb);
            for (int i=0; i<mb; i++) {
                sb.append('a');
            }

            try {
                long time = System.currentTimeMillis();
                write(sb.toString());
                while(read() == null);
                time = System.currentTimeMillis() - time;
                zeit.setText("Letzte Zeit: " + time);
            } catch(Exception e) {
                e.printStackTrace();
            }

        }  else if(ae.getSource() == exit) {
            try {
                server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
button send1 sendet die 256kb (actionlistener).

@edit: im nachhinein fällt mir auf dass read und write relativ gleich bei server und client sind 😉
 
Zuletzt bearbeitet:
Hi,

auf den ersten Blick fällt mir nur auf, dass deine read Methoden in Schleifen aufgerufen werden und diese erzeugen jedesmal eine neue Instanz von BufferedReader und diese werden nicht wieder sauber geschlossen.

Hast du deine Anwendung schon einmal mit VisualVM analysiert? Evtl. gibt es ein Memory Problem, welches die Performanz runterzieht.
 
guter tipp, ich habe versucht eine close methode zu finden aber ich erinnere mich, bei string buffer geguckt zu haben :bloed: (daher also die schönen methoden wie append beim buffer :lol: ).

ich habe jetzt also jeweils ein datenfeld für den printwriter und einen fürn bufferedreader. sie werden im konstruktor deklariert und beim schließen geclosed.

ist aber immernoch das selbe problem: beim jedem durchlauf 2 sekunden länger
1) 2984 msek
2) 5596 msek
3) 7624 msek
4) 9682 msek
5) 11685 msek
6) 13766 msek
...

@edit: jaaaaaa..... ich hab mal die System.out.println(s.getInetAddress() + " sent: "+t); auskommentiert und es sind nur noch 10 - 30 millisekunden.... aber! nach ca. 20 tests hab ich gesehen dass die ergebnisse immer eindeutiger werden: irgendwann nach 10 versuchen kommen nur noch die 10 und die 28 vor

@last edit: ich hab die datenmenge mal auf 10 mb erhöht und da ist das ergebnis noch besser: zwischen 368 und 373 millisekunden ohne fehlwerte. funktioniert also jetzt.
danke an torsan

@closed
 
Zuletzt bearbeitet:
mal eine andere Frage. Wieso wird die read Method in einer While-Schleife ausgeführt und auf Null gecheckt?
Der BufferedReader blockiert doch solange bis der server.getInputStream() fertig ist.
 
das auf null checken: wenn der client weg ist und der server versucht zu readen, dann gibt er null aus. deshalb soll dann der client entfernt werden (indem mit throw new exception die try catch ausgeführt wird).
ich konnte auch für jeden clienten einen neuen thread erstellen und readen aber das wollte ich mir mal ersparen 😉.

mein problem war nämlich:
clienten schicken strings, server muss antworten und clienten messen zeit. deshalb in einer while schleife: der test wird 100 mal genommen und die durchschnittszeit ausgegeben
 

Zurück
Oben