Java(网络):在客户端和服务器之间传递增量值
我应该有多个客户端连接到localhost,在连接客户端之后,他可以按add按钮将值增加1。例如,有两个客户机(A和B)。A单击Add按钮,值(ctr)增加1(ctr=1),如果B单击Add按钮,值(ctr)再次增加1(ctr=2) 但我正努力为一个客户获得正确的结果,所以我将坚持先解决为一个客户获得正确结果的问题,然后再继续从多个客户获得正确结果。但我也希望有人能在多个客户方面为我提供帮助 我不太擅长联网,并尝试实现这一点,这里我的逻辑仅适用于一个客户机 -在ButtonActionListener中,每次按下Add按钮时,我都会将消息“Add”从客户端发送到服务器 -服务器收到消息“add”,并将“ctr”变量增加1 -服务器将把递增的ctr传递给客户端 但是,在我点击了3次Add按钮之后,我从代码中得到的输出非常复杂且不稳定 我的输出Java(网络):在客户端和服务器之间传递增量值,java,sockets,Java,Sockets,我应该有多个客户端连接到localhost,在连接客户端之后,他可以按add按钮将值增加1。例如,有两个客户机(A和B)。A单击Add按钮,值(ctr)增加1(ctr=1),如果B单击Add按钮,值(ctr)再次增加1(ctr=2) 但我正努力为一个客户获得正确的结果,所以我将坚持先解决为一个客户获得正确结果的问题,然后再继续从多个客户获得正确结果。但我也希望有人能在多个客户方面为我提供帮助 我不太擅长联网,并尝试实现这一点,这里我的逻辑仅适用于一个客户机 -在ButtonActionListe
Starting SomeProcess
1500476704 <--Incremented value passed back to client from the server, it should return 1
SomeProcess took 4 ms
Starting SomeProcess
1751217765 <--Incremented value passed back to client from the server, it should return 2
SomeProcess took 0 ms
Starting SomeProcess
543387502 <--Incremented value passed back to client from the server, it should return 3
SomeProcess took 0 ms
Server.java
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
@SuppressWarnings("serial")
public class Server extends JPanel {
private Socket threadSocket;
private JTextArea textArea = new JTextArea(30,30);
public Server() {
add(textArea);
textArea.setEditable(false);
Thread t = new Thread(new acceptClient());
t.start();
}
class acceptClient implements Runnable {
@Override
public void run() {
try {
ServerSocket sSocket = new ServerSocket(4444);
textArea.append("Server started at: " + new Date());
while(true) {
Socket socket = sSocket.accept();
ClientThread cT = new ClientThread(socket);
new Thread(cT).start();
}
} catch(IOException exception) {
System.out.println("Error: " + exception);
}
}
}
class ClientThread extends Thread {
String temp = " ";
DataOutputStream outputInt = null;
int ctr = 0;
PrintWriter output;
public ClientThread(Socket socket) {
threadSocket = socket;
}
@Override
public void run() {
while(true) {
try {
output = new PrintWriter(threadSocket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(threadSocket.getInputStream()));
output.println("You have connected at: " + new Date());
textArea.append("\nClient connected\n");
temp = input.readLine();
if(temp.equals("add")) {
synchronized(this) {
ctr++;
textArea.append(Integer.toString(ctr));
outputInt.write(ctr);
}
}
} catch(IOException exception) {
System.out.println("Error: " + exception);
}
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new Server());
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
}
});
}
}
看看您的写/读过程 首先,你的服务器
output = new PrintWriter(threadSocket.getOutputStream(), true);
output.println("You have connected at: " + new Date());
//...
ctr++;
outputInt.write(ctr);
但你的客户只会
DataInputStream inputInt = new DataInputStream((socket.getInputStream()));
System.out.println(inputInt.readInt());
…这意味着您实际读取的是您在以下位置连接的:“+new Date()
服务器响应
你需要确保阅读内容的顺序与写作顺序相同
我可以考虑的是简化过程……而不是引入<代码> DATAOUTPATSWORDS,我将继续使用<代码> PrimTrriste<代码>您已经设置并简单地做了一些类似的事情…
ctr++;
textArea.append(Integer.toString(ctr));
output.println(ctr);
try (PrintWriter output = new PrintWriter(threadSocket.getOutputStream(), true)) {
try (BufferedReader input = new BufferedReader(new InputStreamReader(threadSocket.getInputStream()))) {
while (true) {
output.println("You have connected at: " + new Date());
textArea.append("\nClient connected\n");
temp = input.readLine();
if (temp != null) {
if (temp.equals("add")) {
synchronized (this) {
ctr++;
textArea.append(Integer.toString(ctr));
output.println(ctr);
}
}
}
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
而是在服务器中
在客户机上,您可以这样做
System.out.println(input.readLine());
System.out.println(input.readLine());
将读取“连接”消息和计数器
旁注
关于您的服务器ClientThread
有几件事与我有关
while循环中重新创建PrintWriter
和BufferedReader
,事实上,输出
实际上不需要是类实例变量
异常
,则运行
方法将永远不会退出,这意味着您可能会陷入一个永无止境的循环synchronized
块,因为ctr
是这个线程上下文中的一个实例字段,所以除非有什么东西试图在外部对其进行更改,否则这只是额外的开销……但我暂时不考虑它ctr++;
textArea.append(Integer.toString(ctr));
output.println(ctr);
try (PrintWriter output = new PrintWriter(threadSocket.getOutputStream(), true)) {
try (BufferedReader input = new BufferedReader(new InputStreamReader(threadSocket.getInputStream()))) {
while (true) {
output.println("You have connected at: " + new Date());
textArea.append("\nClient connected\n");
temp = input.readLine();
if (temp != null) {
if (temp.equals("add")) {
synchronized (this) {
ctr++;
textArea.append(Integer.toString(ctr));
output.println(ctr);
}
}
}
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
相反
虽然我知道您可以使用单个
try with resource
语句,但为了清晰起见,我想将两个流创建分开…感谢您的详细建议。我会考虑这一点