【问题标题】:Java simple chat - Sending message to all clientsJava 简单聊天 - 向所有客户端发送消息
【发布时间】:2016-08-15 17:46:42
【问题描述】:

我正在学习如何用 Java 编程,我决定编写简单的聊天程序。

我已经编写了 Server、Client 和 ThreadedConnection 类。我现在的目标是将来自一个客户的消息显示在其他客户上。 我当前的代码按以下方式工作:当一个客户端发送消息时,其他客户端只有在发送自己的消息时才会收到它。 例子: 客户1: 你好
你好
客户2 嗨
你好
客户3 怎么了

我认为问题在于我从服务器获取输入的方式。可能我的程序正在等待,直到它从用户(stdin)获得输入并且它阻止了程序的其他部分的执行。但老实说,我不知道如何以其他方式做到这一点。

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

如果有任何提示,我将不胜感激。我试图在互联网上找到答案,但通常我找到的程序对我来说太难理解了。

服务器代码:

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);
            }
        }
    }
}

【问题讨论】:

标签: java sockets io chat


【解决方案1】:

如果您想同时从控制台和套接字接收消息,您应该将这些功能拆分为两个线程。所以控制台阅读器将留在主线程中(就像在您的实际代码中一样),但套接字阅读器应该在一个新线程中。

发生这种情况是因为 BufferedReader 的函数readLine() 一直等到接收到下一个输入。这意味着只有当您在控制台中输入一些文本时才会调用您的套接字阅读器。

【讨论】:

  • 不客气;)(将我的答案标记为解决方案:p)
猜你喜欢
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多