我创建了一个简单的服务器类和一个简单的客户端类。我有两个连接到服务器的客户端程序。客户端和服务器类可以发送和接收消息。
问题在于,当两个客户端都连接到服务器时,其中一个客户端可以向服务器发送多条消息,而另一个客户端只能向服务器发送一条消息。
这是我的服务器类的构造函数:
public MyServer () {
setUpConnection ();
}
以下是将客户端连接到端口的代码:
public void setUpConnection () {
clientOutputStreams = new ArrayList ();
try {
serverSocket = new ServerSocket (5000);
while (true) {
Socket clientSocket = serverSocket.accept ();
printWriter = new PrintWriter (clientSocket.getOutputStream ());
clientOutputStreams.add (printWriter);
Thread thread = new Thread (new clientHandler (clientSocket));
thread.start();
System.out.println ("Client is connected to server");
}
} catch (Exception e) {
e.printStackTrace ();
}
}
这是将服务器收到的消息发送到其他客户端的代码:
public void tell everyone (String message) {
Iterator outputObject = clientOutputStreams.iterator();
while (outputObject.hasNext()) {
try {
PrintWriter writer = (PrintWriter) outputObject.next();
writer.println (message);
writer.flush ();
} catch (Exception e) {
e.printStackTrace ();
}
}
}
这是在监听客户端发送的消息的单独线程中运行的代码:
public class clientHandler implements Runnable {
Socket clientSocket;
public clientHandler (Socket socket) {
try {
clientSocket = socket;
isr = new InputStreamReader (clientSocket.getInputStream());
reader = new BufferedReader (isr);
} catch (Exception e) {
e.printStackTrace ();
}
}
public void run () {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println ("I recieved message: " + message);
tellEveryone (message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
这是我的客户端类的构造函数:
public MyClient() {
initComponents();
setUpConnection ();
Thread thread = new Thread (new recievingMessages ());
thread.start ();
jtaRec.setEditable (false);
jtfSend.addFocusListener (this);
jtfSend.requestFocus();
}
以下是客户端按下发送按钮时运行的代码:
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
writer.println (jtfSend.getText ());
System.out.println (jtfSend.getText ());
writer.flush ();
System.out.println ("message has sent");
} catch (Exception e) {
e.printStackTrace ();
}//CLOSE CATCH STATEMENT
jtfSend.setText ("");
jtfSend.requestFocus();
}
以下是将客户端连接到服务器的代码:
public void setUpConnection () {
try {
socket = new Socket ("127.0.0.1", 5000);
writer = new PrintWriter (socket.getOutputStream ());
stream = new InputStreamReader (socket.getInputStream ());
reader = new BufferedReader (stream);
System.out.println ("Connection Made");
} catch (Exception e) {
e.printStackTrace ();
}
}
以下代码在单独的线程中运行并监听服务器发送的消息:
public class recievingMessages implements Runnable {
public void run () {
String message;
try {
while ((message = reader.readLine ()) != null) {
jtaRec.append (message + "\n");
System.out.println ("I recieved the message" + " " + message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我尝试寻找解决方案,但我只是不明白为什么一个客户端只能发送一条消息,而另一个客户端可以发送多条消息,即使两个程序共享同一个类。
最佳答案
我玩了一下你的网络代码,它似乎工作正常。
我的意思是,两个客户端都能够发送和接收多条消息:
#### server logs #### ### Jack logs ### ### Gill logs ###
Starting server
Client is connected to server Jack connected
SRV:1 received: Jack: Aa #1 SND:Jack - Jack: Aa #1
RCV:Jack - Jack: Aa #1
Client is connected to server SND:Jack - Jack: Aa #2 Gill connected
SRV:1 received: Jack: Aa #2 RCV:Jack - Jack: Aa #2 RCV:Gill - Jack: Aa #2
SRV:2 received: Gill: Zz #1 RCV:Jack - Gill: Zz #1 RCV:Gill - Gill: Zz #1
SND:Gill - Gill: Zz #1
SRV:2 received: Gill: Zz #2 RCV:Jack - Gill: Zz #2 RCV:Gill - Gill: Zz #2
SND:Gill - Gill: Zz #2
SRV:1 received: Jack: Aa #3 RCV:Jack - Jack: Aa #3 RCV:Gill - Jack: Aa #3
SND:Jack - Jack: Aa #3
SRV:2 received: Gill: Zz #3 RCV:Jack - Gill: Zz #3 RCV:Gill - Gill: Zz #3
SND:Gill - Gill: Zz #3
SRV:2 received: Gill: Zz #4 RCV:Jack - Gill: Zz #4 RCV:Gill - Gill: Zz #4
SND:Gill - Gill: Zz #4
SRV:1 received: Jack: Aa #4 SND:Jack - Jack: Aa #4
RCV:Jack - Jack: Aa #4 RCV:Gill - Jack: Aa #4
SRV:2 received: Gill: Zz #5 RCV:Jack - Gill: Zz # RCV:Gill - Gill: Zz #5
SND:Gill - Gill: Zz #5
SRV:1 received: Jack: Aa #5 SND:Jack - Jack: Aa #5
RCV:Jack - Jack: Aa #5
最有可能的是,在您的情况下,其中一个客户端连接得太晚,无法获取完整的历史记录,因为此功能未在服务器端实现。
此外,您的一个客户端可能过早断开连接并丢失了部分历史记录。
为了进一步分析丢失消息的原因,您可能需要提供 UI 代码的详细信息(如何在 initComponents()
中构建 UI 并运行客户端应用程序)。
如果您在 GUI 线程之外更改 UI 组件,则可能无法更新它们,因此调用 jtaRec.revalidate()
可能会有所帮助。
关于java - 我不明白为什么我的一个客户端程序无法向服务器发送多于一条消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61155632/