如何以正确的顺序输出我的自动化客户端-服务器 Java 网络代码?
首先让我说我知道这是很多代码,所以请多多包涵.我正在做一个项目,我正在移植
我已经在 pastebin 上链接了完整的代码
FixedMessageSequenceClient
FixedMessageSequenceServer
FixedMessageSequenceProtocol
在代码中,我使用的是一个简单的整数文本日志文件:
<代码>1234
注意:我正在使用 Apache ReversedLinesFileReader 库.
我怀疑我的错误是因为 Java IO 写入时间过长.我想可能是因为这段代码:
<代码>
for (int i = modlastNum; i < KKJokes.length ; i++){String fromServer = br.readLine();out.println(KKJokes[ i % KKJokes.length ]);如果 ( (i % 3 )==2){尝试 {线程.sleep(11);} 捕捉(InterruptedException 即){}}//fromServer = br.readLine();System.out.println ( fromServer );fromServer = br.readLine();System.out.println ( fromServer );//String fromServer3 = br.readLine();System.out.println(fromServer3);System.out.println(fromServer);if(fromServer.equals("inputOfYes")){while (!(fromServer.equals("nowlogged"))) {fromServer = br.readLine();}}System.out.println(fromServer);}//从 Ln 开始的 end-forLoop.93
所以我的预感是,我向 FixedMessageSequenceServer
类(通过 FixedMessageSequenceProtocol
类)自动发送查询的速度可能太快了,也许是 IOFixedMessageSequenceClient
内部是一个瓶颈.
感谢您提供有关如何调试或解决此问题的任何提示,谢谢
解决方案不需要新的答案.感谢上面的 Paul,鼓励我自己解决:
问题是,我忽略了 FixedSequenceMessageProtocol
类的重要性
由于客户端被硬编码以发送大型 StateResponses
数组中的所有内容,因此它需要有第四个字段用于ack"(理想情况下应该是一个多维数组),它与服务器发送nowlogged":
StateResponses[] = { "已授予权限.", "什么是阿拉巴马州人口", "y", "ack",//00许可授予.", "什么是阿拉斯加人口", "y", "ack",
在此之后,在 FixedSequenceMessageProtocol
类中,我添加了一个新的常量 final 变量,以指示我们记录状态位置后的挂起状态,SENTPERMISSION2
:
private static final int WAITING = 0;私有静态最终 int SENTPERMISSION = 1;私有静态最终 int SENTPERMISSION2 = 2;//** 新队私有静态最终 int SENTCLUE = 3;私有静态最终 int ANOTHER = 4;
接下来,我只需要在 FixedSequenceMessageProtocol
类的嵌套 if 块中添加另一个案例:
/* 更多代码 */{if (theInput.equalsIgnoreCase(clues[currentPopulationRequest])) {theOutput = answers[currentPopulationRequest] + "想要另一个?(y/n)";当前人口请求++;状态 = SENTPERMISSION2 ;//sentpermssion2, &在 sentPermission2 中放另一个} 别的 {theOutput = "你应该说"" +线索[currentPopulationRequest] +!再试一次.请求发送一个州人口";状态 = SENTPERMISSION;}}否则如果(状态 == SENTPERMISSION2){if (theInput.equalsIgnoreCase("y")) {theOutput = "状态记录";状态=另一个;} 别的 {theOutput = "再见.";状态=等待;}}否则如果(状态==另一个){if (theInput.equalsIgnoreCase("ack")) {/* etc more code */
Let me start by saying I know this is a lot of code, and so please bear with me. I am working on a project, where I'm porting Oracle's Knock-Knock client/server example into a US State-Capital example. So instead of KnockKnock jokes, it runs a series of state-capital queries. It runs roughly like this :
Server: May I have permission to send you a state-capital query?
Client: Ok
Server: Send me a state , so I can send a capital?
Client: Alabama
Server: The capital of Alabama is Hunstville . Want another one (y/n) ?
Client: n
The motivation for doing this project is to later demonstrate some type of fail-safe ability (after I get this to work I want to use Powershell and use that to run the client-server as a single unit).
Back to my code. When I run it it's giving me the following output, which is not what I'm looking for. It is supposed to be synchronized so that the client and server are working on one state at a time. Instead, the client-side is jumping ahead of the server side, and it isn't reaching the last state of Wyoming. I tried to add in some synchronization as per this question.
I've linked the full code on pastebin
FixedMessageSequenceClient
FixedMessageSequenceServer
FixedMessageSequenceProtocol
In the code, I am using a simple text log file of integer numbers :
1
2
3
4
Note: I am utilizing the Apache ReversedLinesFileReader library .
I have a suspicion that my error is because of Java IO writing takes too long. I think it may be because of this block of code:
for (int i = modlastNum; i < KKJokes.length ; i++){
String fromServer = br.readLine();
out.println(KKJokes[ i % KKJokes.length ]);
if ( (i % 3 )==2){
try {
Thread.sleep(11);
} catch (InterruptedException ie) {}
}
// fromServer = br.readLine(); System.out.println ( fromServer ); fromServer = br.readLine(); System.out.println ( fromServer ); // String fromServer3 = br.readLine(); System.out.println ( fromServer3 ) ; System.out.println ( fromServer ) ;
if(fromServer.equals("inputOfYes")){
while (!(fromServer.equals("nowlogged"))) {
fromServer = br.readLine();
}
}
System.out.println ( fromServer ) ;
} // end-forLoop starting at Ln. 93
And so my hunch is that my automated sending of queries to the FixedMessageSequenceServer
class (by way of the FixedMessageSequenceProtocol
class ) is perhaps going too fast, and maybe the IO inside of FixedMessageSequenceClient
is a bottleneck.
any tips regarding how to debug this or figure out are appreciated, thanks
解决方案No need for new answers. Thanks to Paul above, for encouraging me to figure it out on own :
The issue was that, I overlooked the importance of FixedSequenceMessageProtocol
class
Since the Client is hard-coded to send everything in the large StateResponses
array, it needed to have a fourth field for "ack" (should ideally be a multidimensional array), which pairs with the Server's sending of "nowlogged" :
StateResponses[] = { "Permission granted." , "What is Alabama population", "y", "ack", //00
"Permission granted." , "What is Alaska population", "y", "ack",
After this, in the FixedSequenceMessageProtocol
class I added a new constant final variable, to indicate the pending-status after we log a state position, SENTPERMISSION2
:
private static final int WAITING = 0;
private static final int SENTPERMISSION = 1;
private static final int SENTPERMISSION2 = 2; // ** new line
private static final int SENTCLUE = 3;
private static final int ANOTHER = 4;
Following, I just need to add another case within the nested-if blocks in the FixedSequenceMessageProtocol
class:
/* etc more code */ {
if (theInput.equalsIgnoreCase(clues[currentPopulationRequest])) {
theOutput = answers[currentPopulationRequest] + " Want another? (y/n)";
currentPopulationRequest++;
state = SENTPERMISSION2 ; //sentpermssion2, & in sentPermission2 put another
} else {
theOutput = "You're supposed to say "" +
clues[currentPopulationRequest] +
"! Try again. Request to send a state population";
state = SENTPERMISSION;
}
}
else if (state == SENTPERMISSION2) {
if (theInput.equalsIgnoreCase("y")) {
theOutput = "Status logged";
state = ANOTHER;
} else {
theOutput = "Bye.";
state = WAITING;
}
}
else if (state == ANOTHER) {
if (theInput.equalsIgnoreCase("ack")) { /* etc more code */
相关文章