我正在编写一个应该与某些嵌入式设备通信的服务器。通信协议基于固定长度的报头。问题是我无法让我的服务器正确处理设备的突然断开(“突然”是指当我关闭设备时的情况)。以下是客户端线程主循环的代码:
while(!terminate) {
try {
// Receive the header
while(totalBytesRead < ServerCommon.HEADER_SIZE) {
bytesRead = dis.read(headerBuffer, bytesRead, ServerCommon.HEADER_SIZE - bytesRead);
if(bytesRead == -1) {
// Can't get here!
}
else {
totalBytesRead += bytesRead;
}
}
totalBytesRead = 0;
bytesRead = 0;
type = Conversion.byteArrayToShortOrder(headerBuffer, 0);
length = Conversion.byteArrayToShortOrder(headerBuffer, 2);
// Receive the payload
while(totalBytesRead < length) {
bytesRead = dis.read(receiveBuffer, bytesRead, length - bytesRead);
if(bytesRead == -1) {
// Can't get here!
}
else {
totalBytesRead += bytesRead;
}
}
totalBytesRead = 0;
bytesRead = 0;
// Pass received frame to FrameDispatcher
即使关闭设备,read方法也会返回0,而不是-1。这怎么可能?
答案 0 :(得分:2)
当您正常关闭套接字时,在客户端和服务器之间发送一系列代码来协调它(从结束端的FIN代码开始)。在这种情况下,这种情况不会发生(因为您只是关闭设备),因此服务器不知道发生了什么。
您可能希望通过超时等调查配置,或者某种定时协议通过缺少响应来识别断开连接(可能是使用ICMP / UDP的带外心跳?)。或者是一种无连接协议,如UDP用于您的通信?
答案 1 :(得分:1)
只有当提供的长度为0时,才应返回0。如果出现错误,则应返回-1或抛出异常。
我建议您先调试服务器程序。创建一个java客户端应用程序(应该很容易)。杀死客户看看会发生什么。甚至更好地使用两台PC并突然拔掉它们。这将更好地模拟您的情况。
答案 2 :(得分:0)
对于无法访问的通信伙伴,TCP有30秒超时。我想如果你等了30秒,你应该得到-1。