2015-10-18 253 views
-1

後會發生什麼我有服務器套接字代碼,內螺紋我這樣做:接受客戶端的Java服務器套接字

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     while (true) { 
      try { 

       Socket socket = my_serverSocket.accept(); 
       PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 

       out.println("hi"); 
       BufferedReader in = new BufferedReader(new InputStreamReader(socket 
         .getInputStream())); 
       String msg = in.readLine(); 
       System.out.println("message is: " + msg); 

       in.close(); 
       socket.close(); 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } catch (SecurityException se) { 
       se.printStackTrace(); 
      } 
     } 
    } 
}).start(); 

在這裏,重要的地方是代碼,我打印的「喜」。我感興趣的是接受作品的方式。我的服務器是否向客戶端發送「hi」,並且由於socket.close()行而關閉了套接字,或者連接是否會在其他線程中保留。我希望很明顯,很難解釋我的問題。

我需要的是打開連接,然後在服務器代碼(她在while循環或其他地方)從隊列中讀取數據(即靜態公共)並在可用時將數據發送到客戶端。當數據不可用時等待,只要數據在隊列中發送。這是生產者消費者的問題,並嘗試作爲folows:

protected static BlockingQueue<String> q; 
q = new LinkedBlockingQueue<String>(); 

我首先聲明BlockedQueue。然後,而不是打印「嗨」我想要一些while循環或什麼。我可以這樣做:

if (!q.isEmpty()){ 
    try { 
     String temp = q.take(); 
     out.println(temp); 
    }catch(InterruptedException e){ 
     Log.d("yerchik", "couldn't take from queue: "+ e.getMessage()); 
    } 
} 

我想阻塞隊列處理競爭條件本身。

+1

請問在讀取['Socket#close'](https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#close--)的javadoc後,題? –

+0

accept()只是創建套接字。你爲什麼關閉socket?一旦關閉了套接字,將不會通過套接字發送任何內容。任何關閉輸入流和套接字的原因?其他部分 - >你想保持條件或條件爲q.isEmpty()嗎? –

+0

@ravindra,是的,我希望我的服務器在整個連接期間向客戶端發送消息,並且我只能有一個客戶端。我擔心可以在裏面寫另一個,而我會從隊列中讀取字符串並將它們發送給客戶端。 – yerassyl

回答

0

我不確定爲什麼你不能讓多個客戶端獲取消息,但是你需要在accept()之後忽略或拒絕其他客戶端。每個接受都會創建一個新的套接字連接,我想你可以關閉。只是不要關閉第一個。

至於你的公共靜態隊列,我總是喜歡有一個可運行的某種類型的套接字工作器,並在其構造器中接受從accept()返回的套接字。

另外,您可以使用公共方法(如queueMessage(消息消息))在此套接字worker中創建一個隊列,以便任何其他線程可以將其添加到該對象的消息隊列中。 run()方法會隨着消息的進入而持續循環並消耗此消息隊列(使用同步訪問),並通過連接的套接字傳遞它們。您可以在套接字連接時循環。

同樣,多連接沒有問題 - 每個工作線程都有自己的消息隊列。

相關問題