-1

Hi this is my code for sending data through a socket to another device connected to the network

try {
     PrintWriter printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
     printWriter.print(data);
     Log.d("error", printWriter.checkError() + "");
     printWriter.flush();
} catch (IOException e) {
     Log.d("socket","is disconnected");
     e.printStackTrace();
}

the problem is printWriter.checkError() is always returning false and the IOException never happens. for disconnecting socket I'm turning device off and trying to send data again. even reading from InputStream doesn't help

private class SocketHandler extends AsyncTask<Void, byte[], Void> {
    InputStream in;
    @Override
    protected void onPreExecute() {
        try {
            in = socket.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        super.onPreExecute();
    }
    @Override
    protected Void doInBackground(Void... voids) {
        byte[] content = new byte[2048];
        if (in != null) {
            while (true) {
                try {
                    if (in.available() > 0) {
                        int n = in.read(content);
                        if (n == -1) {
                            break;
                        }
                        publishProgress(new byte[][]{Arrays.copyOfRange(content, 0, n)});
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    @Override
    protected void onProgressUpdate(byte[]... values) {
        String data = new String(values[0]);
        super.onProgressUpdate(values);
    }
    @Override
    protected void onPostExecute(Void aVoid) {
        Log.d("socket", "is disconnected");
    }
}

read never returns -1 so I can detect the socket is disconnected. What can I do?

edit: It's not duplicate of JAVA : Handling socket disconnection because I did everything mentioned there

Amir_P
  • 8,322
  • 5
  • 43
  • 92
  • 'I did everything mentioned there': no you didn't. I mentioned there, and here, 'you should use a read timeout.' – user207421 Aug 02 '17 at 10:37

2 Answers2

0
if (in.available() > 0) {

You never call read() unless there is data available to be read without blocking.

                    int n = in.read(content);
                    if (n == -1) {
                        break;

Unreachable.

                }

And here if available() was zero you do nothing except spin mindlessly smoking the CPU.

Cure: remove the available() test. It isn't doing anything useful, and it is preventing you from detecting end of stream.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

I had the same problem. I used a timer to send connection check command every second in both side and in that timer I checked the last time that I received this connection check command and if it's over for example 10 seconds, then I decided that the socket is disconnected

tOut = new Timer();
tOut.schedule(new TimerTask() {
    @Override
    public void run() {
        long dif = System.currentTimeMillis() - lastCCReceivedTime;
        if (dif > 1000 * 10) {
            // socket is disconnected
            return;
        }


        try {
            out.println("Connection check");
        } catch (Exception e) {
            if (out != null)
                out.close();

            // socket is disconnected
        }
    }
}, 1000, 1000);

Save the last time that the command was received

while ((msg = in.readLine()) != null) {
    lastCCReceivedTime = System.currentTimeMillis();
    //Message received
}
user207421
  • 305,947
  • 44
  • 307
  • 483
SiSa
  • 2,594
  • 1
  • 15
  • 33