英文:
How to continuously send messages between clients?
问题
我有一个简单的客户端/服务器应用程序,可以将2个客户端分组,并使它们彼此之间通信;如果连接了第三个客户端,则该客户端将无法与另外两个客户端通信,但会创建另一组包含2个客户端的新群组,依此类推... 然而,问题出现在当我从一个客户端发送消息时,它不会立即发送消息到另一个客户端,而是等待第一个客户端输入,同时也等待第二个客户端的输入,只有当两个客户端都输入了内容后,它才将消息发送给彼此。非常感谢任何帮助。
服务器:
public class ChatServer {
Socket previousSocket = null;
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9001);
System.out.println("The chat server is running.");
Socket previousSocket = null;
while (true) {
Socket newSocket = serverSocket.accept();
/**
* if (previousSocket == null) 仅当只有1个客户端连接时发生,它会被设置为 previousSocket,
* 然后我们等待第二个客户端连接,所以在此期间不会发生任何操作
*
* 如果第二个客户端加入,我们可以开始在2个客户端的群组之间进行通信
*/
if (previousSocket == null) {
previousSocket = newSocket;
} else {
new Handler(previousSocket, newSocket).start();
new Handler(newSocket, previousSocket).start();
previousSocket = null;
}
}
}
private static class Handler extends Thread {
private String name;
private Socket socket;
private Socket peerSocket;
private DataInputStream in;
private DataOutputStream out;
public Handler(Socket socket, Socket peerSocket) {
this.socket = socket;
this.peerSocket = peerSocket;
}
public void run() {
try {
while (true) {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(peerSocket.getOutputStream());
try {
String input = in.readUTF();
out.writeUTF(input);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端:
public class ChatClient {
public static void main(String[] args) throws UnknownHostException, IOException {
new ChatClient();
}
public ChatClient() throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9001);
System.out.println("You can start typing:");
while(true) {
Scanner scanner = new Scanner(System.in);
Thread input = new Thread() {
@Override
public void run() {
while(true) {
try {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
System.out.println(message);
// 从服务器读取消息
String received = inputStream.readUTF();
System.out.println(received);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
input.start();
Thread output = new Thread() {
public void run() {
try {
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
if(message.equalsIgnoreCase("quit")) {
socket.close();
break;
}
outputStream.writeUTF(message);
}
} catch (IOException e) {
e.printStackTrace();
}
};
};
output.start();
}
}
}
英文:
I have a simple client/server application that groups 2 clients and makes them communicate between eachother and if a third client got connected it would not be able to communicate with the 2 other clients but it would create another group of 2 clients and so on... However the problem occurs when i send a message from a client it doesn't immediately send it over to the other client instead it waits for the first client input and it also waits for the second clients input and only when both clients have entered an input it sends them over to eachother. Any help is very appriciated.
Server:
public class ChatServer {
Socket previousSocket = null;
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9001);
System.out.println("The chat server is running.");
Socket previousSocket = null;
while (true) {
Socket newSocket = serverSocket.accept();
/**
* if (previousSocket == null) occurs if only 1 client is connected and its being set as a previousSocket
* and we wait for a second client to connect so meanwhile nothing happens
*
* if second clients joins in we can start communicating in groups of 2
*/
if (previousSocket == null) {
previousSocket = newSocket;
} else {
new Handler(previousSocket, newSocket).start();
new Handler(newSocket, previousSocket).start();
previousSocket = null;
}
}
}
private static class Handler extends Thread {
private String name;
private Socket socket;
private Socket peerSocket;
private DataInputStream in;
private DataOutputStream out;
public Handler(Socket socket, Socket peerSocket) {
this.socket = socket;
this.peerSocket = peerSocket;
}
public void run() {
try {
while (true) {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(peerSocket.getOutputStream());
try {
String input = in.readUTF();
out.writeUTF(input);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Client:
public class ChatClient {
public static void main(String[] args) throws UnknownHostException, IOException {
new ChatClient();
}
public ChatClient() throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9001);
System.out.println("You can start typing:");
while(true) {
Scanner scanner = new Scanner(System.in);
Thread input = new Thread() {
@Override
public void run() {
while(true) {
try {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
System.out.println(message);
//reading messages from server
String received = inputStream.readUTF();
System.out.println(received);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
input.start();
Thread output = new Thread() {
public void run() {
try {
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
if(message.equalsIgnoreCase("quit")) {
socket.close();
break;
}
outputStream.writeUTF(message);
}
} catch (IOException e) {
e.printStackTrace();
}
};
};
output.start();
}
}
}
答案1
得分: 2
移除顶层的while
循环,并在客户端从服务器读取时移除scanner.nextLine()
。我已经更新了你的客户端代码如下,这应该可以正常工作。
public class ChatClient {
public static void main(String[] args) throws UnknownHostException, IOException {
new ChatClient();
}
public ChatClient() throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9001);
System.out.println("You can start typing:");
Scanner scanner = new Scanner(System.in);
System.out.println("got it");
Thread input = new Thread() {
@Override
public void run() {
try {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
while (true) {
String received = inputStream.readUTF();
System.out.println(received);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
input.start();
Thread output = new Thread() {
public void run() {
try {
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (message.equalsIgnoreCase("quit")) {
socket.close();
break;
}
outputStream.writeUTF(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
output.start();
}
}
英文:
Remove top level while
loop and remove scanner.nextLine()
while reading from server, in client.
I have updated your client code below, this should work fine.
public class ChatClient {
public static void main(String[] args) throws UnknownHostException, IOException {
new ChatClient();
}
public ChatClient() throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9001);
System.out.println("You can start typing:");
Scanner scanner = new Scanner(System.in);
System.out.println("got it");
Thread input = new Thread() {
@Override
public void run() {
while(true) {
try {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
while(true) {
//String message = scanner.nextLine();
//System.out.println(message);
//reading messages from server
String received = inputStream.readUTF();
System.out.println(received);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
input.start();
Thread output = new Thread() {
public void run() {
try {
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
if(message.equalsIgnoreCase("quit")) {
socket.close();
break;
}
outputStream.writeUTF(message);
}
} catch (IOException e) {
e.printStackTrace();
}
};
};
output.start();
}
}
答案2
得分: 0
你需要将客户端的输入流和输出流分成两个单独的线程。问题在于,在读取输入之前,你的客户端正在等待来自扫描仪的输入。扫描仪是一个阻塞调用,因此它需要它自己的线程。
另外,你应该将数据流的创建从循环中移动到构造函数中...这将提高你的效率。
英文:
You need to separate the input and output streams in the client into two separate threads. The issue is that your client is waiting for input from the scanner before you read the input. Scanner is a blocking call, so it needs it own thread.
Also, you should move the creation of the data streams in the loop to the constructor...that will increase your efficiency.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论