2016-08-15 139 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

相关问题