java套接字服务器和嵌入式设备 - 无法正确处理断开连接
我正在编写一个应该与某些嵌入式设备通信的服务器。 通信协议基于固定长度的标头。 问题是我无法让我的服务器正确处理设备的突然断开连接(“突然”是指我刚刚关闭设备的情况)。 以下是客户端线程主循环的代码:
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。 怎么会这样?
I'm writing a server that is supposed to communicate with some embedded devices. The communication protocol is based on a fixed length header. The problem is I can't get my server to handle sudden disconnects of the devices properly (by "sudden" I mean situations when I just turn the device off). Here is the code for the client thread main loop:
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
Even if I turn the device off, the read method keeps returning 0, not -1. How this could be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您正常关闭套接字时,客户端和服务器之间会发送一系列代码来协调此操作(从关闭端的 FIN 代码开始)。 在这种情况下,这种情况不会发生(因为您只需关闭设备),因此服务器会想知道发生了什么。
您可能希望通过超时等调查配置,或某种定时协议来识别由于缺乏响应而导致的断开连接(可能是使用 ICMP/UDP 的带外心跳?)。 或者是否使用像 UDP 这样的无连接协议来进行通信?
When you close a socket normally, there's a sequence of codes sent between client and server to coordinate this (starting with a FIN code from the closing end). In this instance this isn't happening (since you simply turn the device off), and consequently the server is left wondering what has happened.
You may want to investigate configuration via timeouts etc., or some sort of timed protocol to identify a disconnect through absence of response (perhaps out-of-band heartbeats using ICMP/UDP?). Or is a connectionless protocol like UDP of use for your communication ?
仅当提供的长度为 0 时,Read 才应返回 0。如果出现错误,应返回 -1 或引发异常。
我建议你先调试你的服务器程序。 创建一个 java 客户端应用程序(应该很容易做到)。 杀死客户端看看会发生什么。 最好使用两台电脑并突然拔掉它们的电源。 这将更好地模拟您的情况。
Read is supposed to return 0, only if the supplied length is 0. In case of an error -1 should be returned or an exception be thrown.
I suggest that you debug your server program first. Create a java client application (should be easy to do so). Kill the client to see what happens. Even better use two PCs and suddenly unplug them. This will simulate your situation better.
对于无法访问的通信伙伴,TCP 有 30 秒的超时时间。 我想如果你等 30 秒你应该得到 -1。
TCP has a 30 seconds timeout for communication partners that are not reachable. I suppose if you wait for 30 seconds you should get your -1.