我在调试模式中有这种有趣的行为,我无法向自己解释。 有两个小型客户端和服务器应用程序,流程如下:
客户端启动TCP连接
服务器接受并向客户端发送请求包数据大小的消息(已修复)
客户端发送大小
服务器读取大小并初始化一些字节数组 - 这可以正常工作
来自输入流的read()
上的服务器阻塞等待数据包并且客户端发送数据包。 - 这是罪魁祸首
当我运行应用程序时,这一切都有效,但是当我调试服务器时 - 它只是阻塞read()
。
如果我发送多条消息,例如50,则服务器会收到其中的49条消息。一旦客户端关闭连接,服务器从流中读取-1并退出,第一条消息丢失。
我唯一能想到的是,在调试模式下,客户端在服务器从流中读取消息之前发送消息,但我不知道它是如何相关的,因为消息应该在那里。
有人可以解释我在调试模式下遇到的这种行为吗?
注意:客户端代码仅用于调试,所以它不是最漂亮的。
服务器
private static int sent;
public void processClientInput(HealthCheckSession session) {
byte[] buffer = session.getBuffer();
DataInputStream stream = session.getInFromClient();
int readBytes = 0;
int totalBytes = 0;
try {
while((readBytes = stream.read(buffer)) !=-1) { <---- this blocks in debug on first message
totalBytes += readBytes;
if (totalBytes < buffer.length) {
continue;
}
else {
totalBytes = 0;
String packet = new String(buffer, ProtocolValidator.SERIALIZATION_CHARSET);
sendResponse(packet);
}
}
} catch (IOException e) {e.printStackTrace();}
}
private void sendResponse(String packet) {
System.out.println(packet);
++sent;
System.out.println("sent " + sent);
}
客户端
public static void main(String[] args) throws UnknownHostException,
IOException, InterruptedException {
Socket clientSocket = new Socket("localhost", 10002);
// get the socket's output stream and open a PrintWriter on it
PrintWriter outToServer = new PrintWriter(
clientSocket.getOutputStream(), true);
// get the socket's input stream and open a BufferedReader on it
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
System.out.println("before read");
System.out.println(inFromServer.readLine());
System.out.println("after read");
byte[] packageData = "100, ABCDZEGHR"
.getBytes(Charset.forName("UTF-8"));
String size = String.valueOf(packageData.length);
outToServer.println(size);
for (int i = 0; i < 50; i++) {
DataOutputStream dis = new DataOutputStream(
clientSocket.getOutputStream());
System.out.println("before write");
dis.write(packageData);
dis.flush();
System.out.println("after write");
Thread.sleep(1000);
}
try {
Thread.sleep(100 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clientSocket.close();
}
重要更新
在Netbeans调试模式下不会发生这种情况。