Я работаю над программой, включающей многопоточный сервер, в которой я хочу, чтобы сообщения, отправляемые клиентами, передавались обратно каждому клиенту, подключенному в данный момент к серверу.Это не совсем так.Я отправлю сообщение от клиента на сервер, и оно вернется к тому же клиенту.Не для другого клиента.Допустим, с одним клиентом я последовательно набираю «Один», затем «Два», затем «Три».Обмен будет выглядеть примерно так:
Клиент 1: «Один»
Эхо от сервера ON Консоль клиента 1: «Один»
Клиент 1: «Два»
Эхо от сервера ON Консоль клиента 1: «Два»
Клиент 1: «Три»
Эхо от сервера ON 1 Консоль клиента: «Три»
Эта часть делает то, что должна.Но абсолютно ничего не происходит на консоли клиента 2.Допустим, обмен выше уже произошел.Экран клиента 2 по-прежнему будет пустым.Затем я наберу что-нибудь в Client 2, скажем, «Test».Сервер ответит Клиенту 2 «Один».Допустим, я снова набираю «Test» в Client 2. Сервер ответит «Two».Вы поняли идею.Я не уверен, почему он это делает.У меня есть три файла: Клиент, Сервер и один, предназначенный для управления соединениями между ними.
РЕДАКТИРОВАТЬ: Я думаю, я знаю проблему!В строке 43 в клиенте консоль ожидает некоторого пользовательского ввода, прежде чем он продолжится.Я думаю, поэтому, когда первый клиент отправляет пользовательский ввод, он получает правильный ответ, а второй - нет: потому что второй клиент ничего не вводил в консоль, и он все еще ожидает некоторого ввода, чтобыпродолжить.Любые идеи о том, как обойти это?
Клиент:
package client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
//The socket for the client
Socket sock;
//The stream to read incoming data
DataInputStream din;
//The stream to send outgoing data
DataOutputStream dout;
public static void main(String[] args) {
//Create a new client
new Client();
}
public Client() {
try {
//Activate the socket to the host and port
sock = new Socket("localhost", 4444);
//Open the input and output streams
din = new DataInputStream(sock.getInputStream());
dout = new DataOutputStream(sock.getOutputStream());
//Start listening for user input
listenIn();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void listenIn() {
//Monitors the console for user input
Scanner userIn = new Scanner(System.in);
while(true) {
//While there is nothing left to read from the console
while(!userIn.hasNextLine()) {
try {
//Ensures resources aren't constantly being used by listening for input
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Get line from user input
String input = userIn.nextLine();
//if user exits the client, break the loop and exit the program
if(input.toLowerCase().equals("quit")) {
break;
}
try {
//outputs user input to Server
dout.writeUTF(input);
//Flushes all data out of the data output stream's buffer space
dout.flush();
//While there's nothing to read from the input stream, save resources
while(din.available() == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//When there's incoming data, print it to the console
String reply = din.readUTF();
System.out.println(reply);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
//Close all the I/O streams and sockets, so there aren't memory leaks
try {
din.close();
dout.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Сервер:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
//The server's socket
ServerSocket sSock;
ArrayList<ServerConnection> connections = new ArrayList<ServerConnection>();
boolean run = true;
public static void main(String[] args) {
//Create a new server
new Server();
}
public Server() {
try {
//Initialize the server socket to the correct port
sSock = new ServerSocket(4444);
//While the socket should be open
while(run) {
//Initialize the client socket to the correct port
Socket sock = sSock.accept();
//Create a new server connection object between the client socket and the server
ServerConnection sConn = new ServerConnection(sock, this);
//Start the thread
sConn.start();
//Add the connection to the arraylist
connections.add(sConn);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Подключение к серверу:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class ServerConnection extends Thread{
Socket sock;
Server server;
DataInputStream in;
DataOutputStream out;
boolean run = true;
//Create the server connection and use super to run it with Thread's constructor
public ServerConnection(Socket socket, Server server) {
super("ServerConnectionThread");
this.sock = socket;
this.server = server;
}
public void sendOne(String text) {
try {
//Write the text to the output stream
out.writeUTF(text);
//Flush the remaining data out of the stream's buffer space
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
//Send a string to every client
public void sendAll(String text) {
/*Iterate through all of the server connections in the server
and send the text to every client*/
for(int i = 0; i < server.connections.size(); i++) {
ServerConnection sc = server.connections.get(i);
sc.sendOne(text);
}
}
public void run() {
try {
//Set the input stream to the input from the socket
in = new DataInputStream(sock.getInputStream());
//Set the output stream to write out to the socket
out = new DataOutputStream(sock.getOutputStream());
//While the loop should be running (as determined by a boolean value)
while(run) {
//While there is no incoming data, sleep the thread to save resources
while(in.available() == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Store the incoming data in a string
String textIn = in.readUTF();
//Send it to all clients
sendAll(textIn);
}
//Close datastreams and socket to prevent memory leaks
in.close();
out.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}