2016-06-30 72 views
1

我們創建了java(在Windows /服務器上的eclipse)和android應用程序(android studio/client)之間的服務器客戶端關係。溝通看起來很好,但有時連接速度非常慢,直到應用和服務器不再響應。但是,沒有給出真正的錯誤,並且連接順利或緩慢時沒有任何模式。serverSocket.accept()緩慢或無響應

我們在堆棧查找答案,但我們只能找到有關輸出和輸入流的答案。但是,一旦建立了連接(serverSocket.accept()),程序運行良好,流創建速度非常快。因此我們認爲問題在於服務器端創建套接字。該程序只需處理最多30個客戶端,並且唯一的通信存在字符串(所以不需要大量的數據傳輸)。

注意:當一個連接接受速度很慢時,來自客戶端的下一個上傳請求必須等待。當輪到他們時,他們再次隨機快速或被服務器緩慢接受。所有連接都在端口8080上進行。

我們的服務器和客戶端的代碼在下面給出,有人知道爲什麼連接(在某些隨機時間)這麼慢嗎?

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); 
     } 
    } 

客戶線程代碼:(如果慢沒有達到)

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" 
    } 

客戶端(安卓)

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(); 
    } 

非常感謝!

回答

0

原來我們有路由器問題。將所有平板電腦和計算機連接到本地熱點時,它運行得非常流暢!坦克大家的幫助:D

+0

不要忘了標記你的答案是正確的:-)。 –

-1

編輯:嘗試BufferedStreamReader這裏提到:Java socket performance bottleneck: where?

相反的:

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

用途:

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

,並與沖洗:

sOutput.flush(); 

同去對於InputStream,使用BufferedInputStream。

+0

您是否在serverSocket.accept()之前或之後添加此代碼; ? – Anne

+0

接受後,我將代碼添加到我的答案上面 – babadaba

+0

沒有幫助:(仍然沒有從clientthread的構造函數autputput :( – Anne

0

您應該將您的主服務器循環(while(keepGoing)...)解壓縮到運行方法中,並使服務器實現Runnabel接口。然後創建一個新的線程並啓動它。

例子:

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.... 
    } 
} 

我希望你得到了我想要說什麼,否則只是評論,我將升級我的例子;)

+0

這已經是這樣了,我忘了將它包含在代碼標題中,藉口: )生病更新標題 – Anne

0

你應該在ClientThread流在run()方法,在你開始循環之前。不在構造函數中。否則,你正在接受線程中進行I/O操作,這會降低速度。

我不知道你爲什麼要在客戶端創建一個線程,只是立即加入它。

+0

我試着重新定位了流代碼的創建,問題似乎變得更糟了關於連接的位置:我跟着一個教程(第一次服務器客戶端編程g)並複製代碼段。我不知道爲什麼它在那裏,我應該刪除它嗎? – Anne

+0

您應該刪除*線程*。這不僅僅是'連接的位置'。質量差的代碼無論其來源。 – EJP

+0

請發佈您的當前代碼。將其編輯到您的問題中。 – EJP