我正在学习如何使用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);
我会非常感谢任何提示。我试图在互联网上找到答案,但通常我发现的程序对我来说太难理解了。
服务器代码:
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 :(得分:0)
如果要同时从控制台和套接字接收消息,则应将这些功能分成两个线程。因此,控制台读取器将保留在主线程中(就像在实际代码中一样),但套接字读取器应该在新线程中。
这是因为BufferedReader的函数readLine()
等待直到收到下一个输入。这意味着只有在控制台中输入某些文本时才会调用套接字读取器。