【发布时间】:2011-05-16 01:08:01
【问题描述】:
我的 Java 程序有问题。它在服务器和许多客户端之间有一个套接字连接。这是服务器(涉及问题的部分):
private static ArrayList<ParallelServer> clientConnected = new ArrayList<ParallelServer>();
public Server(int port) {
this.port = port;
if (!startServer())
JOptionPane.showMessageDialog(new JFrame(""),
"Error!", "ERROR!",
JOptionPane.ERROR_MESSAGE);
}
private boolean startServer() {
try {
server = new ServerSocket(port);
loadDatabase();
} catch (IOException ex) {
ex.printStackTrace();
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return true;
}
public void runServer() {
while (true) {
try {
client = server.accept();
ParallelServer pServer = new ParallelServer(client);
clientConnected.add(pServer);
Thread thread = new Thread(pServer);
thread.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void sendBroadcast(String username) throws IOException {
for(int i = 0; i < clientConnected.size(); i++)
clientConnected.get(i).sendAnswer("@change," + username);
}
并行服务器是:
private Socket client;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private PrintWriter printwriter;
public ParallelServer(Socket client) {
this.client = client;
}
public void run() {
try {
inputstreamreader = new InputStreamReader(client.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
printwriter = new PrintWriter(client.getOutputStream(), true);
String lineread = "";
while (client.isConnected()) {
lineread = bufferedreader.readLine();
doCommand(lineread);
}
} catch (UnknownHostException unhe) {
} catch (InterruptedIOException intioe) {
} catch (IOException ioe) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void sendAnswer(String answer) throws IOException {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.println(answer);
printwriter.flush();
}
这里是客户端:
private String serverurl = "localhost";
private int serverport = 7777;
private PrintWriter printwriter;
private InputStreamReader inputstreamreader;
private BufferedReader bufferedreader;
private Socket server;
public Client() {
server = null;
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROE!",JOptionPane.ERROR_MESSAGE);
}
}
public String sendCommand(String command) throws IOException {
if(server == null) {
try {
server = new Socket(serverurl, serverport);
server.setSoTimeout(5000);
} catch (UnknownHostException unhe) {
System.out.println("UnknownHostException: " + unhe.getMessage());
} catch (InterruptedIOException intioe) {
System.out.println("Timeout while attempting to establish socket connection.");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROR!",JOptionPane.ERROR_MESSAGE);
}
}
if(server != null) {
printwriter = new PrintWriter(server.getOutputStream(), true);
printwriter.println(command);
printwriter.flush();
inputstreamreader = new InputStreamReader(server.getInputStream());
bufferedreader = new BufferedReader(inputstreamreader);
return bufferedreader.readLine();
}
else
return "@serverProblem";
}
该程序是一个简单的回合制在线游戏。玩家的回合是通过队列创建的,当玩家通过他的回合时,服务器会发送一条广播消息,上面写着“现在是'玩家 1' 回合”。 (例如)。我的问题是,当客户端收到消息时,它就像添加答案“现在轮到‘玩家 1’了。”到它将收到的下一条消息。在我的例子中:当一个玩家通过他的回合时,他会发送“@passTurn,username”。 ParallelServer 类从队列中轮询它,将其放在队列的底部,向客户端发送“@ok”以告诉它轮到已成功更改,并告诉服务器类发送广播消息。然后,当同一个客户端尝试做进一步的动作时,它会考虑“现在轮到‘玩家 1’”。作为服务器给它的答案。相反,我希望服务器和客户端像往常一样工作,并且当广播消息发出时,客户端会收到通知,而不会产生任何附带影响。 我能做些什么? 谢谢。
【问题讨论】:
-
您的输出是在控制台还是 IDE 中?另外,您确定您没有查看正在缓冲的上一条消息吗?
-
@Vern:我的输出是一个 IDE。关于缓冲区,它发生这样的事情:客户端发送“@passTurn”->服务器发送“@ok”->客户端接收它->服务器然后发送“@changeTurn,player1”(客户端什么都不做,因为它没有发送消息并且它不等待答案)-> 客户端发送“@otherAction”并读取“@changeTurn,player1”作为答案。
-
那么,在该消息交换的哪个点它失败了?
-
我希望客户端检测到“@changeTurn,player1”,但现在它不能检测到,因为它只检测到使用“sendCommand”的类的答案。每个使用它的班级都喜欢:“我发送这个然后我收到这个”。但是对于广播消息,没有“我发送这个”,因为服务器发送它时没有收到客户端的任何命令,所以没有“我收到这个”。即使我将在“readAnswer”(if(...readLine().contains(“changeTurn”))..) 中放置一个“if else”,也不会检测到它,因为任何类都没有调用“readAnswer” (客户端不知道会发送“@changeTurn”)。
-
既然如此,这听起来更像是你需要改变你的消息传递机制。此外,您可能想要查看我在下面的回复中建议的非阻塞双向消息。文字太多,无法发表评论。
标签: java sockets client message