views:

311

answers:

3

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?

+2  A: 

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 ?

Brian Agnew
+1  A: 

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.

kgiannakakis
A: 

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.