2016-08-15 180 views
0

我正在學習如何在Java中編程,並決定編寫簡單的聊天程序。Java簡單聊天 - 向所有客戶端發送消息

我已經寫了Server,Client和ThreadedConnection類。我現在的目標是向其他客戶展示其中一個客戶的消息。 我目前的代碼工作方式如下:當一個客戶端發送消息時,其他客戶端只有在他們發送自己的消息時纔會收到該消息。 例如: 客戶端1: 你好
你好
客戶端2 喜
你好
Client3 怎麼了

我認爲這個問題是在我從服務器獲取輸入的方式。可能我的程序正在等待,直到它從用戶(stdin)獲得輸入,並阻止程序的其他部分的執行。但老實說,我不知道如何以其他方式做到這一點。

if((message=stdin.readLine())!=null) 
      out.println(message); 
if((message=in.readLine())!=null) 
      System.out.println(message); 

我會非常gratefull任何提示。我試圖在網上找到答案,但通常我發現的程序太難以理解了。

Server代碼:

import java.io.*; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 

public class Server { 

    private static List<ThreadedConnection> clientList=new ArrayList<>();; 

    public synchronized void broadcastMessageToAllClients(String message){ 

     for(ThreadedConnection tc: clientList) 
      tc.sendMessage(message); 
    } 

    public static void main(String[] args) throws IOException { 

     try { 

      Server server=new Server(); 
      ServerSocket serverSocket = new ServerSocket(8189); 

      while (true) { 

       Socket socket = serverSocket.accept(); 
       Runnable threadedServer = new ThreadedConnection(socket, server); 
       clientList.add((ThreadedConnection)threadedServer); 
       Thread thread = new Thread(threadedServer); 
       thread.start(); 
      } 
     } catch (Exception e) { 

      System.out.println("An error occured."); 
      e.printStackTrace(); 
     } 
    } 
} 

ThreadedConnection代碼:

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class ThreadedConnection implements Runnable { 

    private Server server; 
    private Socket socket; 
    private PrintWriter out; 
    private BufferedReader in; 

    public ThreadedConnection(Socket socket, Server server) { 

     this.socket = socket; 
     this.server = server; 
    } 

    @Override 
    public void run() { 

     try { 

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

      String message; 
      while(true){ 

       if((message=in.readLine())!=null) 
        server.broadcastMessageToAllClients(message); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendMessage(String message){ 

     out.println(message); 
    } 
} 

客戶端代碼:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class Client { 

    public static void main(String[] args) throws IOException { 

     try (
       Socket socket = new Socket("127.0.0.1", 8189); 
       PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
       BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); 
     ) { 

      String message; 
      while(true){ 

       if((message=stdin.readLine())!=null) 
        out.println(message); 
       if((message=in.readLine())!=null) 
        System.out.println(message); 
      } 
     } 
    } 
} 
+0

您應該有一個專用於從套接字讀取的線程。此外,你可能想看看ServerSocketEx(https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/),這是一個處理套接字的框架 – ControlAltDel

+0

謝謝,我會努力工作它。 – drapo

回答

0

如果你想從控制檯,並從該插座接收消息同時,您應該將這些函數分成兩個線程。所以控制檯閱讀器會留在主線程中(因爲它在你的實際代碼中),但是套接字閱讀器應該在一個新的線程中。

發生這種情況是因爲BufferedReader的函數readLine()一直等到下一個輸入被接收。這意味着只有在控制檯中鍵入文本時纔會調用套接字閱讀器。

+0

感謝您的回答,它工作得很好:) – drapo

+0

不客氣;)(標記我的答案爲解決方案:p) – Creart

相關問題