更新时间:2022-03-25 23:14:25
每个新客户端应位于服务器端单独的 Thread
上,您要分配一个 new
Socket
到您的 serviceSocket
,基本上就忽略了以前连接的客户端。
Every new client should be on seperate Thread
on server side, you are assigning a new
Socket
to your serviceSocket
and by that you basically ignore previously connected clients.
您为新连接的客户端启动新服务器
,而不是启动 Thread
。您应该为每个连接的客户端创建一个新套接字
,并在 new线程
上运行它,而不启动新服务器
客户端连接后。
You start a new Server
instead of starting a Thread
for the client that just connected. You should create a new Socket
for every client that is connected and run it on a new Thread
not start a new Server
after a client was connected.
更新
以下是基本的多客户端服务器的示例:
Here is an example of a basic multiple client 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();
}
}
}
这不是***的例子,但我希望您可以使用它并根据您的需要进行调整。
It's not the best example but I hope you can work with it and tweak it to your needs.