2016-06-30 5 views
1

Wir haben eine Server-Client-Beziehung zwischen Java (Eclipse auf Windows/Server) und Android App (Android Studio/Client) erstellt. Die Kommunikation scheint gut, aber manchmal ist die Verbindung sehr langsam, bis die App und der Server nicht mehr reagieren. Es ist jedoch kein echter Fehler gegeben und es gibt kein Muster, wenn die Verbindung gut geht oder wenn es langsam ist.serverSocket.accept() langsam oder nicht reagierend

Wir haben hier auf Stapel nach Antworten gesucht, aber wir konnten nur Antworten bezüglich der Ausgangs- und Eingangsströme finden. Sobald jedoch die Verbindung (serverSocket.accept()) hergestellt ist, läuft das Programm gut und die Streams werden super schnell erstellt. Daher denken wir, dass das Problem bei der serverseitigen Erstellung von Sockets liegt. Das Programm muss nur maximal 30 Clients verwalten, und die einzige Kommunikation besteht aus Strings (also keine enormen Datenübertragungen).

Hinweis: Wenn eine Verbindungsakzeptanz langsam ist, müssen die nächsten kommenden Anforderungen von Clients warten. Wenn sie an der Reihe sind, werden sie wieder sehr schnell oder langsam vom Server akzeptiert. Alle Verbindungen werden auf Port 8080 hergestellt.

Der Code unseres Servers und Clients sind unten angegeben, weiß jemand, warum die Verbindung (zu einigen zufälligen Zeiten) so langsam ist?

SERVER:

public void run() { 
     keepGoing = true; 
    try { 
     serverSocket = new ServerSocket(port); 

     while (keepGoing) { 
      display("Server waiting for Clients on port " + port + "."); 

      Socket socket = serverSocket.accept(); //<---our problem 
      if (!keepGoing)  break; 
      ClientThread t = new ClientThread(socket, this); //<---program doesnt reach this code when it is slow. One client thread exists for each connection. 
    }catch (IOException e) { 
     String msg = sdf.format(new Date()) 
       + " Exception on new ServerSocket: " + e + "\n"; 
     display(msg); 
     } 
    } 

Client-Thread Code:

(nicht, wenn langsam erreicht)
public ClientThread(Socket socket, Server s) { 
     this.server = s; 
     this.socket = socket;   
    System.out.println("Thread trying to create Object Input/Output Streams"); 
    try { 
     // make streams 
     sOutput = new ObjectOutputStream(socket.getOutputStream()); 
     sInput = new ObjectInputStream(socket.getInputStream()); 

     // read user account info 
     String input = (String) sInput.readObject(); 
     String[] accountInfo = input.split(";"); 
     username = accountInfo[0]; 
     password = accountInfo[1]; 
    } "catch all problems" 
    } 

CLIENT (android)

Thread connect = new Thread(new Runnable() { 
    @Override 
     public void run() 
     { 
      try 
      { 
       socket = new Socket(ip.getText().toString(), portNr); 
       sOutput = new ObjectOutputStream(socket.getOutputStream()); 
       sInput = new ObjectInputStream(socket.getInputStream()); 
      } 

      catch (UnknownHostException e){ 
       e.printStackTrace(); 
      } catch(IOException e){ 
       e.printStackTrace(); 
      } 

      "sending account information" 
     } 
    }); 
    connect.start(); 
    try { 
     connect.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

Thanks so much!

Antwort

0

Es stellte sich heraus, dass wir ein Router-Problem hatten.Wenn alle Tablets und Computer an einen lokalen Hotspot angeschlossen wurden, lief es super flüssig! Speichert alle für die Hilfe: D

+0

Vergessen Sie nicht, Ihre Antwort als die richtige zu markieren :-). –

-1

EDIT: Versuchen Sie, ein BufferedStreamReader hier erwähnt: Java socket performance bottleneck: where?

Statt:

sOutput = new ObjectOutputStream(socket.getOutputStream()); 

Verwendung:

sOutput = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream())); 

und spülen Sie es mit:

sOutput.flush(); 

Das Gleiche gilt Verwenden Sie für den InputStream BufferedInputStream.

+0

Haben Sie diesen Code vor oder nach dem ServerSocket.accept() hinzugefügt? ? – Anne

+0

Nach dem Akzeptieren, fügte ich den Code zu meiner Antwort über – babadaba

+0

Nicht helfen :(noch keine autput von dem Konstruktor von clientthread :( – Anne

0

Sie sollten Ihre Hauptserverschleife (while (keepGoing) ...) in eine run-Methode extrahieren und den Server dazu bringen, die Runnabel-Schnittstelle zu implementieren. Dann erstelle einen neuen Thread und starte ihn.

Beispiel:

public class Server implements Runnable{ 
    private Thread thread; 
    public Server(){ 
     thread = new Thread(this); 
     thread.start(); //I would create start() and stop() methods but for simplicity I just use thread.start() 
    } 

    @Override 
    public void run(){ 
     //while.... 
    } 
} 

Ich hoffe, Sie bekommen, was ich sagen will, sonst nur kommentieren, und ich werde mein Beispiel aktualisieren;)

+0

das ist bereits der Fall, ich habe vergessen, es in die Code-Beschriftung aufzunehmen, Ausreden:) ill update die Beschriftung – Anne

0

Sie sollen die Ströme in den ClientThread im run() Verfahren machen , bevor Sie mit dem Schleifen beginnen. Nicht im Konstruktor. Andernfalls machst du I/O im Accept-Thread, was es verlangsamt.

Ich habe keine Ahnung, warum Sie einen Thread im Client erstellen, nur um sofort beizutreten.

+0

Ich habe versucht, die Erstellung von Streams Code verschieben, schien das Problem zu bekommen. Über den Speicherort der Join: Ich folgte einem Tutorial (ersten Mal Server-Client programmin g) und kopierte Teile des Codes. Ich weiß nicht, warum es dort auch ist, sollte ich es entfernen? – Anne

+0

Sie sollten den * Thread * entfernen. Es geht nicht nur um den Ort des Beitritts. Schlechter Qualitätscode, egal aus welcher Quelle. – EJP

+0

Bitte senden Sie Ihren aktuellen Code. Bearbeiten Sie es in Ihre Frage. – EJP