[英]Multithreaded client server chat application in java
I'm trying to write multithreaded client server chat application in java. 我正在尝试用Java编写多线程客户端服务器聊天应用程序。 I just want to create two threads, send from every thread some numbers, and get the same numbers from server.
我只想创建两个线程,从每个线程发送一些数字,然后从服务器获取相同的数字。 But something is going wrong.
但是出了点问题。 Client sends numbers just from one thread and Server returns not all numbers
客户端仅从一个线程发送数字,而服务器不返回所有数字
Here is client code 这是客户代码
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);
}
}
}
And server code 和服务器代码
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);
}
}
}
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
上,您要为serviceSocket
分配一个new
Socket
,这样您就基本上会忽略以前连接的客户端。
You start a new Server
instead of starting a Thread
for the client that just connected. 您启动一个
new Server
而不是为刚刚连接的客户端启动一个Thread
。 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. 您应该为每个连接的客户端创建一个
new Socket
,并在连接客户端后在不启动new Server
的new Thread
上运行它。
UPDATE UPDATE
Here is an example of a basic multiple client server: 这是基本的多客户端服务器的示例:
The server code consists of a few classes: 服务器代码由几个类组成:
// 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();
}
}
And the Client example: 和客户端示例:
// 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. 这不是最好的例子,但我希望您可以使用它并根据需要进行调整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.