gpt4 book ai didi

java - Java 中的多客户端聊天应用程序

转载 作者:行者123 更新时间:2023-11-30 12:05:15 24 4
gpt4 key购买 nike

我刚开始接触套接字编程,所以为了加深对它的理解,我想构建一个多客户端聊天应用程序。

我打算这样做的方式如下:应用程序启动后,您有两个选择:创建服务器或加入服务器。

如果您选择创建一个服务器,一个新线程将启动并托管服务器,然后另一个线程将启动,它将创建一个新客户端并自动连接到刚刚构建的服务器。

在这里我遇到了以下问题。每个客户端都可以向服务器发送消息,但为了使所有客户端的消息保持同步,我正在考虑将检索到的消息从服务器重定向到所有客户端,如下图所示。 enter image description here

问题是,当我尝试在客户端和服务器上监听和发送时,我得到了这个错误。

java.net.SocketException: Connection reset
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:200)
at java.base/java.io.DataInputStream.readUnsignedShort(DataInputStream.java:342)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:594)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:569)
at parctice.Server.lambda$main$0(Server.java:32)
at java.base/java.lang.Thread.run(Thread.java:835)

这是我的服务器:

int port = 4444;

try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("server starts port = " + serverSocket.getLocalSocketAddress());


while(true){
Socket socket = serverSocket.accept();
System.out.println("accepts : " + socket.getRemoteSocketAddress());

DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());


String[] message = {""};

new Thread(() -> {
try {
while(in.available() > 0){
System.out.println("SERVER > " + in.readUTF());
message[0] = in.readUTF();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();

System.err.println(message[0]);
try {
out.writeUTF(message[0] + "REDIRECTED MESSAGE");
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

和我的客户:

int portNumber = 4444;
System.out.println("CLIENT > Trying to connect to the server...");
try {
Socket socket = new Socket("localhost", portNumber);

DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());


new Thread(() -> {
try {
while(in.available() > 0){
System.out.println("SERVER > " + in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();


try {
out.writeUTF("test");
} catch (IOException e) {
e.printStackTrace();
}

} catch (IOException e) {
e.printStackTrace();
}

最后,我想问问你们,你们是否认为我尝试使用的逻辑是正确的,如果不正确,请告诉我哪里出了问题,如果可能的话,你们能解释一下为什么我不能够同时在客户端和服务器上收听和发送?因为当我尝试通过客户端发送数据并在服务器上检索它时它工作得很好,但我想完成双向通信。

最佳答案

我发现这个解决方案似乎适用于这种情况第一次我们创建服务器:

private List<ClientThread> clients; // or "protected static List<ClientThread> clients;"


public List<ClientThread> getClients(){
return clients;
}
private void startServer(){
clients = new ArrayList<ClientThread>();
try {
serverSocket = new ServerSocket(PORT);
System.out.println("SERVER ON");
System.out.println("SERVER > Waiting for connections...");


// ACCEPT ALL CONNECTIONS
while (true){
try {
Socket socket = serverSocket.accept();
System.out.println("SERVER > New connection: " + socket.getRemoteSocketAddress());
ClientThread client = new ClientThread(this, socket);
Thread thread = new Thread(client);
thread.start();
clients.add(client);
} catch (IOException e) {
e.printStackTrace();
System.out.println("SERVER > Accept failed");
}
}

} catch (IOException e) {
e.printStackTrace();
}
}

然后我们为每个客户创建一个新线程

public class ClientThread implements Runnable {

private Socket socket;
private Server server;
private String clientName;

public String getClientName() {
return clientName;
}

public void setClientName(String clientName) {
this.clientName = clientName;
}

public Socket getSocket() {
return socket;
}

public void setSocket(Socket socket) {
this.socket = socket;
}

public ClientThread(Server server, Socket socket) {
this.server = server;
this.socket = socket;
}

@Override
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

out.writeUTF("HI FROM SERVER");
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
// UNCOMMENT TO READ ON SERVER
// System.out.println("SERVER > " + input);
for (ClientThread thatClient : server.getClients()){
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input + " GOT FROM SERVER");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

客户:

    public void createClient(){
try {
socket = new Socket("localhost", portNumber);
// socket = new Socket(getHost(), portNumber);

DataInputStream in = new DataInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
String input = in.readUTF();
System.out.println(getUserName() + " > " + input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}

关于java - Java 中的多客户端聊天应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56454187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com