2016-04-21 41 views
0

客戶端和服務器之間可以進行成功的對話。但是,這隻有在客戶端和服務器之間發送一條消息的情況下。Java套接字客戶端/服務器對一次只能發送一條消息

實施例(工程):

Client: Hello 
Server: helloo 
Client: what time is it 
Server: Let me get that for you 

實施例(不工作):

Client: Hello 
Server: helloo 
Server: *How are you today* 
Server: *test message* 
Client: Yes 

星號之間的消息不在客戶端,直到所述客戶端發送呈現2個消息。根據我的理解,它似乎像一個網絡消息系統一樣工作,其中服務器發送的消息數量必須等於客戶端發送的消息數n + -1,以顯示所有消息。

客戶端代碼:

try { 
      Socket client_socket= new Socket(hostname,port_number); 
      PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true); 
      BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream())); 
      BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in)); 

      String fromUser,fromServer; 
      while ((fromServer=input.readLine())!=null) { 
       System.out.println("Server: "+fromServer); 
       if (fromServer.equals("Quit")) { 
        break; 
       } 
       fromUser=stdIn.readLine(); 
       if (fromUser!=null) { 
        System.out.println("Client: "+fromUser); 
        output.println(fromUser); 
       } 

      } 

     } 

服務器端代碼:

try { 
      ServerSocket server_socket=new ServerSocket(port_number); 
      Socket client_socket= server_socket.accept(); 
      PrintWriter output = new PrintWriter(client_socket.getOutputStream(),true); 
      BufferedReader input = new BufferedReader(new InputStreamReader(client_socket.getInputStream())); 
      BufferedReader stdIn=new BufferedReader(new InputStreamReader(System.in)); 
      output.println("Established"); 
      String fromUser, fromServer; 
      while ((fromUser=input.readLine())!=null) { 
       System.out.println("Client: "+fromUser); 
       if (fromUser.equals("Quit")) { 
        break; 
       } 
       fromServer=stdIn.readLine(); 
       if (fromServer!=null) { 
        System.out.println("Server: "+fromServer); 
        output.println(fromServer); 
       } 
      } 

     } 

看代碼,我可以明白爲什麼會發生這種事,它是因爲While循環之後的SOP初始化停止等待1行輸入的代碼,然後等待發送自己的句子,然後再接收另一個。我試圖將這些放在if語句中,但是這完全沒有任何交流。

我似乎無法弄清楚如何解決這個問題。

如果這需要線程,有沒有另一種方式? (我不太熟悉線程)

+0

您需要花更多時間學習TCP套接字如何工作。你的問題有無數的例子 – redFIVE

+0

我經歷的許多例子都有隻有一條消息發送的問題。隨後的消息只會在套接字關閉時顯示。另外,我也嘗試尋找更多的例子,並閱讀它們,似乎無法找到很多(一些進入線程) – user2883071

+0

你還沒有看夠硬,這不是一些獨特的隱晦的用例 – redFIVE

回答

1

根據程序的性質,我建議你使用更多的線程來處理消息。

讓我們先從服務器: 如果服務器有多個客戶端,比它很可能是明智的,每一個客戶區分與一個線程,例如:

  ServerSocket ss; 

      try { 
       ss = new ServerSocket(portIn); 
       while (true) { 
        Socket s = ss.accept(); 
        // Option 1: runnable class 
        new Thread(new CustomRunnableClass(s)).start(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

或者,如果你不想你的「會話管理器」是一個自定義運行的類,你可以用下面的

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     new SomeClass().runThisClass(); 
    } 
} 

在客戶端更換線路new Thread(new CustomRunnableClass(s)).start();我建議偵聽新消息從插座任何類將是分銷商通過一個新的線程nguished:

private void startListening() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      for(;;) { 
       String msg = dis.readUTF(); 
       System.out.println(" ----- Recieved New Message -----\n" + msg); 
       for (IMessageListener listener : listeners) { 
        try { 
         listener.onMessageRecieved(msg); 
        } catch (Exception e) { 

        } 
       } 
      } 
     } 
    }).start(); 
} 

這種方式,客戶端偵聽客戶端接收到的任何消息和運行方法來處理他們在接收,以及在此期間沒有被掛起。

希望這有幫助。

+0

看完這個後..我在線程上做了一個快速的崩潰過程,如果我正確地理解了這個,服務器接受一個新的套接字連接並將它傳遞給一個線程..所以所有的bufferereading和printwriting都將在某處的'public void run'方法中其他。但是,我仍然沒有看到這將如何解決問題(相同的while循環也將在線程中)。我不太確定客戶端正在做什麼?這是一個線程聆聽和定期主要方法發佈? – user2883071

-1

您需要非阻塞套接字,如果輸入緩衝區中沒有數據,閱讀器函數應該中間返回。

http://www.java2s.com/Tutorials/Java/Java_Network/0070__Java_Network_Non-Blocking_Socket.htm

+0

線程的使用可以解決這個問題,但是在真實服務器中爲每個傳入套接字創建一個線程是一個糟糕的主意,請想象有多少線程會有正在運行的http服務器stackoverflow –

+0

您可能會驚訝多少。你沒有任何證據證明SO服務器沒有使用線程。你還沒有真正確定這個問題的問題。質量差的教程。 – EJP

+0

問題是函數readline在數據可用之前不會返回控件。這個問題通過非阻塞IO解決。 –

相關問題