Java套接字-如何向多个线程发送消息



我使用Java制作了一个聊天应用程序(服务器/客户端(。注意:服务器作为自己的jar文件运行,每个客户端作为自己的jar文件运行。

每个客户端都在自己的线程上。

每当我向服务器发送消息时,每个客户端都会收到消息,但是当我从客户端发送消息时只有服务器会收到消息。当客户端发送消息时,我希望所有连接的客户端和服务器都能接收到消息,这样所有客户端都可以一起通信,也可以与服务器通信。

我看了很多关于这方面的帖子和视频,但大多数都太令人困惑了,我无法理解。有人能帮我理解如何在线程之间发送消息吗?谢谢

--我的代码——

客户:

public Client(User user, String address, int port) {
try {
socket = new Socket(address, port);
ClientApplicationUI app = new ClientApplicationUI();
app.setTitle("Chat Application - " + user.getUsername());
app.setVisible(true);
ServerConnection connection = new ServerConnection(socket, app);
output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
new Thread(connection).start();
app.getButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <" + user.getUsername() + "> " + app.getTextField().getText() + "n";
try {
output.writeUTF(message);
output.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
} catch (UnknownHostException e) {
System.out.println(e);
System.out.println("Could not connect! Reason: " + e);
} catch (IOException e) {
System.out.println("Could not connect! Reason: " + e);
}
}

服务器连接

public class ServerConnection implements Runnable {
@SuppressWarnings("unused")
private Socket socket;
private DataInputStream in;
private ClientApplicationUI app;
public ServerConnection(Socket socket, ClientApplicationUI app) throws IOException {
this.socket = socket;
this.app = app;
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
@Override
public void run() {
while (true) {
String message;
try {
message = in.readUTF();
app.logMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

服务器

public class Server {
private Socket socket = null;
private ServerSocket server = null;
private ExecutorService pool = Executors.newFixedThreadPool(4);
public Server (int port) {
try {
ApplicationUI app = new ApplicationUI();
app.setVisible(true);
server = new ServerSocket(port);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Server started!n");
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Waiting for new connections...n");

while (true) {
socket = server.accept();
ConnectionHandler clientThread = new ConnectionHandler(socket, app);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " A new client has been accepted!n");
pool.execute(clientThread);
}

} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server(58139);
}
}

连接处理程序

public class ConnectionHandler implements Runnable {
private Socket client;
private ApplicationUI app;
private DataInputStream in;
private DataOutputStream out;
public ConnectionHandler(Socket client, ApplicationUI app) throws IOException {
this.client = client;
this.app = app;
in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
}
@Override
public void run() {
try {
app.getButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <Server> " + app.getTextField().getText() + "n";
try {
sendMessage(message);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
String message = "";
while (!message.equals("/stop")) {
message = in.readUTF();
app.logMessage(message);
}
} catch (IOException e) {
System.err.println("IO exception in connection handler!");
System.err.println(e.getStackTrace());
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendMessage(String message) throws IOException {
out.writeUTF(message);
out.flush();
}       
}

您需要了解套接字是如何工作的。它们始终是客户端和服务器
有两种方法可以实现您想要的目标:

第一个解决方案:
将适用于所有客户端的消息发送到服务器,并让服务器将消息分发给所有其他客户端。服务器将需要跟踪已经连接的客户端,即存储它们的Socket


第二种解决方案:(这完全不可取(
如果您想在不涉及实际服务器的情况下向网络的客户端发送消息,则需要该客户端充当服务器,或者相反。这意味着每个客户端实际上都需要监听其他客户端,而不仅仅是服务器。

您绝对应该选择第一个解决方案!

最新更新