2014-02-26 103 views
-1

目前我正在學習有關插座和我的家庭作業是創建一個聊天室,多個客戶端可以自由交談控制。老師給出的提示是聊天室服務器只在客戶端試圖發送消息時才接受客戶端。這個作業應該不用線程完成。(客戶端 - 服務器)的Java服務器時的的ServerSocket接受客戶機不能正常工作

下面給出的提示,我試圖在客戶端和服務器代碼都創建未綁定的ServerSocket和Socket。關鍵的想法是,當客戶端嘗試向服務器發送消息時,客戶端代碼將連接未綁定的套接字,然後該套接字將觸發服務器連接未綁定的ServerSocket並接受客戶端。

然而,當我運行的代碼,同時在服務器和客戶端代碼運行,他們要求所有的連接完成,但我無法傳輸客戶端和服務器都之間的消息。

我嘗試過在網上找到答案,但找不到任何答案。我想問一下,如果我決定服務器何時接受客戶端的方式是正確的。

我的聊天室服務器:

public class ChatRoom { 
    public static void main(String[] args) throws Exception { 

     int portNum = 4321; 

     ServerSocket serverSocket = new ServerSocket(); 

     int count = 1; 

     while (true) { 

      // redeclare everything each round 
      Socket socket = null; 
      PrintWriter out = null; 
      BufferedReader in = null; 
      BufferedReader stdIn = null; 
      String inputLine = null; 

      // accept each time round 
      serverSocket.bind(new InetSocketAddress(portNum)); 
      socket = serverSocket.accept(); 
      System.out.println("newly accepted!"); 

      out = new PrintWriter(socket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      stdIn = new BufferedReader(new InputStreamReader(System.in)); 

      if (!((inputLine = in.readLine()).equals("Bye"))) { 
       System.out.println("Client says: " + inputLine); 
       out.println(stdIn.readLine()); 
       out.flush(); 

       System.out.println("Message Count: " + count); 
       count++; 
      } 
      else { 
       out.println(inputLine); 
       serverSocket.close(); 
       socket.close(); 
       out.close(); 
       in.close(); 
      } 
     } 
    } 
} 

我ChatRoomClient:

public class ChatRoomClient { 
    public static void main(String[] args) throws Exception { 
     String hostName = "localhost"; 
     int portNumber = 4321; 

     Socket echoSocket = new Socket(); // creates an unbound socket 

     PrintWriter out = null; 
     BufferedReader in = null; 
     BufferedReader stdIn = null; 

     String userInput; 
     do { 
      out = null; 
      in = null; 
      stdIn = null; 

      // each time round the unbound socket attempts to connect to send a message 
      echoSocket.connect(new InetSocketAddress(hostName, portNumber)); 
      System.out.println("successfully connected"); 
      out = new PrintWriter(echoSocket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); 
      stdIn = new BufferedReader(new InputStreamReader(System.in)); 

      userInput = stdIn.readLine(); 
      out.flush(); 
      System.out.println("Server says: " + in.readLine()); 
     } 
     while (!userInput.equals("Bye")); 

     // close everything 
     echoSocket.close(); 
     in.close(); 
     stdIn.close(); 
    } 
} 

謝謝!

+0

有一些事情是錯的/不在你的代碼中有很多意義。也許[Oracle教程顯示如何做到這一點](http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html)將是一個很好的開始。 –

+0

謝謝!這是一個很好的教程,我會翻閱。但是,是否有可能不使用線程呢? – Imma

+0

@Imma線程是迄今爲止最方便的方法。有可能*不使用線程。如果您一次有數百個連接,您將遇到線程的性能問題,並且必須以其他方式執行此操作,但是如果您沒有多個連接,則只需使用線程即可。 – immibis

回答

0

老師給出的提示是聊天室服務器只在客戶端試圖發送消息時才接受客戶端。這個作業應該不用線程完成。

老師給出沒有意義的暗示。客戶端必須連接,然後服務器才能接受。客戶端無法先發送消息而無法連接。也許老師真的意味着客戶不應該連接,直到他有東西要發送?

根據給出的提示,我試圖在客戶端和服務器代碼中創建未綁定的ServerSocket和Socket。關鍵的想法是,當客戶端嘗試向服務器發送消息時,客戶端代碼將連接未綁定的套接字,然後該套接字將觸發服務器連接未綁定的ServerSocket並接受客戶端。

但這不會發生。不可能。如果您嘗試連接到未偵聽的端口,您將得到一個ConnectException.將端口設置爲偵聽狀態的唯一方法是綁定ServerSocket.服務器不可能知道該端口的魔術後門客戶端想要連接,所以它現在應該做綁定。

這個家庭作業應該是沒有使用線程。

不可能「創建一個聊天室,多個客戶端可以自由交談」這樣一來,除非你預計將使用非阻塞I/O,或濫用available()設施,或使用每封郵件的連接,但那麼我不知道如何將一個客戶端的消息傳達給其他客戶端,除非您允許將它們批量處理。

如你所描述的,這個任務有太多無法估量的方面。提出的問題不具有實際意義,您提出的解決方案當然不適用。您應該繼續以正常方式編寫程序,包括連接,接受和一些I/O。在老師提出澄清時讓它工作。

+0

謝謝!我想我對這個問題有一些誤解haha – Imma

0

啊......對於使用線程的服務器出你將不能夠服務於多個客戶端。無論如何,你目前的代碼有問題,你的邏輯是不正確的。

  • 你的標準輸入應申報和循環之外實例化,你並不需要不斷創造每個循環的標準輸入對象。
  • 你「在」插座接受()和echoSocket.connect()也應循環之外,這就是爲什麼你不是因爲你是不是在同一條線上收聽從服務器得到任何答覆。這就像你的手機,每次都要在FLASH上撥打新號碼。所有指向同一臺服務器,但它是不同的連接。

所以,這個想法是建立一個服務器和客戶端(單一連接),可以通過雙向(通過輸入和輸出流)溝通的連接。然後你就可以循環和說話開始與客戶端,然後服務器接收,然後服務器交談,然後客戶端收到然後客戶交談....直到客戶說再見......

更多:http://ta.cnci.org/basicirc

0

以爲我想更新,我設法解決我的問題,而不使用線程。只是套接字哈哈。認爲這將是很好的張貼我的參考答案..

我的聊天室服務器:

public class ChatRoomServer { 
    public static void main(String[] args) throws Exception { 

     ServerSocket serverSocket = new ServerSocket(4321); 

     while(true) { 
      Socket clientSocket = serverSocket.accept(); 

      BufferedReader in = new BufferedReader 
         (new InputStreamReader(clientSocket.getInputStream())); 

      String inputLine = in.readLine(); 

      System.out.println("Client says: " + inputLine); 

      in.close(); 
      clientSocket.close(); 

     }  

    } 
} 

我的聊天室客戶:

public class ChatRoomClient { 
    public static void main(String[] args) throws Exception { 

     String hostName = "localhost"; 
     int portNum = 4321; 

     BufferedReader stdIn = new BufferedReader 
            (new InputStreamReader(System.in)); 

     while (true) { 

      String userInput; 

      userInput = stdIn.readLine(); 

      Socket echoSocket = new Socket(hostName, portNum); 

      PrintWriter out = new PrintWriter 
             (echoSocket.getOutputStream(), true); 

      out.println(userInput); 
      out.flush(); 

      out.close(); 
      echoSocket.close(); 

      if (userInput.equals("Bye")) { 
       stdIn.close(); 
       break; 
      } 
     } 

    } 
} 
+0

這是一個聊天系統嗎? 「多個客戶可以自由交談」在哪裏?不。 – EJP

+0

Yupp,這是一個在控制檯上運行的聊天系統。我不認爲這是一個真正的聊天系統,因爲我被告知要多次運行客戶端文件來模擬連接到服務器的多個客戶端 – Imma

相關問題