2013-03-08 123 views
3

有一百萬個使用Java套接字的例子 - 每個例子都是一樣的! 每個人都顯示正在創建的客戶端套接字,某些文本正在發送,並且套接字已關閉。使用相同的客戶端套接字將多個消息發送到服務器套接字

我在寫一些測試代碼。我希望我的客戶端循環發送不少消息。每次關閉客戶端套接字並重新創建似乎都很愚蠢,所以我想我只會創建一個客戶端套接字,循環並在同一個套接字上發送數據。事情是 - 雖然我的服務器套接字沒有打印出它收到的內容,直到客戶端發送了最後一條消息並且客戶端套接字關閉。

服務器:

Socket sock; 
ClientConnection client; 

ServerSocket ss = new ServerSocket(portNumber); 
ss.setSoTimeout(0); // 0=infinite 

while (true) { 
    sock = ss.accept(); 
    client = new ClientConnection(sock); 
    new Thread(client).start(); 
    // ClientConnection reads from sock, prints, and closes sock 
} 

ClientConnection(在服務器端一個單獨的類):

public class ClientConnection implements Runnable 
{ 
    private Socket m_socket; 
    private BufferedReader m_in = null; 

    public ClientConnection(Socket socket) 
    { 
     m_socket = socket; 

     try { 
      InputStream inStream = socket.getInputStream(); 
      m_in = new BufferedReader(new InputStreamReader(inStream)); 
     } 
     catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 

    public String getMessage() 
    { 
     String line = null; 
     StringBuffer completeMessage = new StringBuffer(); 

     try { 
      while ((line = m_in.readLine()) != null) 
      { 
       completeMessage.append(line); 
      } 
     } 
     catch (IOException ioe) { 
      ioe.printStackTrace(); 
      return ""; 
     } 

     return completeMessage.toString(); 
    } 

    public void run() 
    { 
     try { 
      String message = getMessage(); 
      System.out.println("Received: " +message); 
     } 
     finally 
     { 
      try { 
       m_socket.close(); 
      } 
      catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
    } 
} 

客戶:

socket = new java.net.Socket(m_destination, m_portNumber); 
outputStream = socket.getOutputStream(); 
printStream = new java.io.PrintStream(outputStream); 

while (more-stuff-to-send) 
{ 
    printStream.print(text); 
    printStream.print("\n"); 
    printStream.flush(); 
} 

prinStream.close(); 
socket.close(); 

ClientConnection由服務器創建的時候我開始客戶端,但它不打印在客戶端完成發送之前發送的內容。

我覺得我錯過了沿線某處。聊天的例子很常見,所以如果我有一個聊天客戶端,那麼它想發送給聊天服務器的每條消息都會創建一個客戶端套接字,發送消息並關閉套接字?不知何故,這似乎不對。

謝謝。

+0

客戶端連接看起來像什麼?注意,從不使用包裝在Socket流中的PrintStream,因爲它隱藏IOExceptions。 – jtahlborn 2013-03-08 19:20:49

+0

ClientConnection代碼是解決此問題的必要信息。也許你可以發帖SSCCE? – Jeremy 2013-03-08 19:34:31

回答

-1
client = new ClientConnection(sock); 

您在構造函數中傳遞套接字。

所以你不應該這樣做:

socket = new java.net.Socket(m_destination, m_portNumber); 

只是緩存是vatiable從構造器如:this.sock = sock; 讓讀者和作者是確定的,也是服務器就可以了。

我會使用一個Vector作爲發送消息的同步隊列,並且while (more-stuff-to-send)循環會檢查隊列和id,而不是睡眠,如果有東西要發送,比彈出第一個併發送它,而他必須做的東西,或者套接字關閉我的客戶端。

+1

請注意,從發佈的代碼中並不明顯,但我相信ClientConnection與包含的「客戶端代碼」是不同的類(ClientConnection是維護與客戶端的連接的服務器端類)。 – jtahlborn 2013-03-08 19:54:20

+0

@jtahlborn對我來說很明顯,除非客戶/老闆明確表示他們想要別的東西,否則我會一直這樣做。在大多數情況下,這是一個完美的解決方案,其他案例不是 – 2013-03-08 21:54:09

+0

您正在混合客戶端代碼和服務器代碼。 ClientConnection類在服務器端。 – EJP 2015-01-07 06:05:14

相關問題