gpt4 book ai didi

java - java中的多线程客户端服务器聊天应用程序

转载 作者:行者123 更新时间:2023-11-30 07:46:33 25 4
gpt4 key购买 nike

我正在尝试用 java 编写多线程客户端服务器聊天应用程序。我只想创建两个线程,从每个线程发送一些数字,并从服务器获取相同的数字。但有些事情出了问题。 Client sends numbers just from one thread and Server returns not all numbers

这是客户端代码

import java.io.*;
import java.net.*;

public class Client implements Runnable{

private Socket clientSocket = null;
private DataInputStream input = null;
private PrintStream output = null;
private DataInputStream inputLine = null;
private int id;

public Client(int id){
this.id = id;
}

public static void main(String[] args) throws IOException, InterruptedException {

System.out.println("The client started. Type any text. To quit it type 'Ok'.");

Client a = new Client(1);
Thread one = new Thread(a);

Client b = new Client(2);
Thread two = new Thread(b);
one.start();
two.start();

one.join();
two.join();

}

public void run() {
System.out.println("hi from thread" + id);
try {
clientSocket = new Socket("localhost", 4444);
output = new PrintStream(clientSocket.getOutputStream());
input = new DataInputStream(clientSocket.getInputStream());
inputLine = new DataInputStream(new BufferedInputStream(System.in));
}
catch( IOException e){
System.out.println(e);
}
String responseLine;
try{
for(int i = 0; i < 10; i++){
output.println( id + " " + i);
System.out.println("sended:" + id + " " + i);
responseLine = input.readLine();
System.out.println("received: " + responseLine);
}
}
catch (IOException e) {
System.out.println(e);
}
}

}

和服务器代码

import java.io.*;
import java.net.*;

public class Server implements Runnable{
private static ServerSocket MyService = null;
private DataInputStream input = null;
private PrintStream output = null;
private String line;
private static Socket serviceSocket = null;

public static void main(String[] args) throws IOException {


try{
MyService = new ServerSocket(4444);
if(args.length > 0){
MyService = new ServerSocket(Integer.parseInt(args[0]));
}
}
catch( IOException e){
System.out.println("Couldn't linputten to port " + (args.length > 0 ? Integer.parseInt(args[0]) : 4444));
}

System.out.println("The server started. To stop it press <CTRL><C>.");
while(true){
try {
serviceSocket = MyService.accept();
new Thread(new Server()).start();
System.out.println("CREATED");
}
catch (IOException e) {
System.out.println("can't accept");
}
}

}

public void run(){
try {
input = new DataInputStream(serviceSocket.getInputStream());
output = new PrintStream(serviceSocket.getOutputStream());
while (true) {
line = input.readLine();
System.out.println("from client:" + line+"\n");
output.println("From server: " + line+"\n");

}

}
catch(IOException e) {
System.out.println(e);
}
}

}

最佳答案

每个新客户都应该单独使用 Thread在服务器端,您分配一个 new Socket给您serviceSocket这样你基本上就忽略了之前连接的客户端。

您启动 new Server而不是开始 Thread对于刚刚连接的客户端。您应该创建一个 new Socket对于每个连接的客户端并在 new Thread 上运行它不启动new Server客户端连接后。

更新

这是一个基本的多客户端服务器的示例:

服务器代码由几个类组成:

// Server.java
public class Server {

private ServerSocket socket;
private ConnectionListener connectionListener;

// temp
private List<Client> clientList = new ArrayList<Client>();
// temp end

public Server(int port) {
try {
socket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}

connectionListener = new ConnectionListener(this);
}

public void start() throws IOException {

connectionListener.start();

// temp will move to a Thread later
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String input;
while (((input = stdIn.readLine()) != null) && connectionListener.isAlive()) {
if (input.equalsIgnoreCase("exit")) {
break;
} else {
for (int i = 0; i < input.length(); i++)
System.out.print("\b");
System.out.println("Admin: " + input);
for (Client c : clientList) {
c.send("Admin: " + input);
}
}

}
stop();
// temp end
}

public void stop() {

connectionListener.stop();
for (Client c : clientList) {
c.closeSession();
}

System.out.println("Server terminated!");
}

public synchronized void addConnection(Connection connection) {

Client c = new Client(connection, clientList);
clientList.add(c);
c.startSession();
System.out.println("Client connected");
}

public ServerSocket getSocket() {

return socket;
}

public static void main(String[] args) throws IOException {

int port;
if (args.length > 0)
port = Integer.parseInt(args[0]);
else
port = 4444;
Server s = new Server(port);
s.start();
}

}
<小时/>
// ConnectionListener.java
public class ConnectionListener implements Runnable {

private Server server;
private ServerSocket socket;
private boolean running;
private Thread t;

public ConnectionListener(Server server) {
this.server = server;
this.socket = server.getSocket();
running = false;
}

public synchronized void start() {

if (running)
return;

running = true;
t = new Thread(this);
t.start();
}

public synchronized void stop() {

if (!running)
return;

System.out.print("Terminating connection listener on:" + socket.getLocalSocketAddress() + "...");

running = false;

try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}

try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("TERMINATED!");
}

@Override
public void run() {

System.out.println("Listening for connections on: " + socket.getLocalSocketAddress());

try {
while (running) {
Socket request = socket.accept();
Connection connection = new Connection(request);
server.addConnection(connection);
}
} catch (IOException e) {
//e.printStackTrace();
}

}

public boolean isAlive() {

return running;
}

}
<小时/>
// Connection.java
public class Connection {

private Socket socket;
private BufferedReader in;
private BufferedWriter out;
private boolean alive;

public Connection(Socket socket) {
this.socket = socket;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
alive = true;
}

public String read() {

try {
if (in.ready()) {
return in.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}

return null;
}

public void write(String data) {

try {
out.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}

public void flush() {

try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}

public boolean close() {

boolean result = true;
try {
in.close();
out.close();
socket.close();
alive = false;
} catch (IOException e) {
e.printStackTrace();
result = false;
}
return result;
}

public boolean isAlive() {

return alive;
}

}
<小时/>
// Client.java

/*
* This is still server side, that is the handler for the connected clients
*/
public class Client implements Runnable {

public static final long IDLE_TIME = 10;

private Connection connection;
private boolean alive;
private Thread t;

private List<Client> clientList;

public Client(Connection connection, List<Client> clientList) {
this.connection = connection;
this.clientList = clientList;
alive = false;
}

public synchronized void startSession() {

if (alive)
return;

alive = true;

t = new Thread(this);
t.start();

}

public synchronized void closeSession() {

if (!alive)
return;

alive = false;

try {
connection.close();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public void run() {

while (connection.isAlive()) {

String in = connection.read();
if (in != null) {
System.out.println(in);
for (Client c : clientList) {
c.send(in);
}
} else {
try {
Thread.sleep(IDLE_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

}

public void send(String msg) {

connection.write(msg + "\n");
connection.flush();
}

}

客户端示例:

// Client.java
public class Client {

public static void main(String[] args) {

String host;
if (args.length > 0)
host = args[0];
else
host = "localhost";

int port;
if (args.length > 1)
port = Integer.parseInt(args[1]);
else
port = 4444;

try (Socket socket = new Socket(host, port);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {

Thread input = new Thread(() -> {
String msg;
try {
while ((msg = in.readLine()) != null) {
System.out.println(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
});
input.start();

String userName = "User" + ((int) (Math.random() * 200));
String msg;
try {
while ((msg = stdIn.readLine()) != null) {
for (int i = 0; i < msg.length(); i++)
System.out.print("\b");
out.write(userName + ": " + msg + "\n");
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
}

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

}

}

这不是最好的示例,但我希望您可以使用它并根据您的需求进行调整。

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

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