1

I have 2 devices connected via Socket

Server Code - (Android app):

log("sending song to client - " + clientSocket.getInetAddress().toString());

            InputStream fileInputStream = new FileInputStream(songFile);
            socketDataOutputStream.writeLong(songFile.length());
            Thread.sleep(50);
            byte[] byteBuffer = new byte[16 * 1024];
            int count;
            while ((count = fileInputStream.read(byteBuffer)) > 0) {
                socketDataOutputStream.write(byteBuffer, 0, count);
            }
            log("song sent to client - " + clientSocket.getInetAddress().toString());
            socketOutputStream.flush();
            log("sending a message to client - " + clientSocket.getInetAddress().toString());
            socketDataOutputStream.writeUTF("play");
            log("message sent to client - " + clientSocket.getInetAddress().toString());

Client Code - (PC code):

OutputStream fos = new FileOutputStream(song);
        InputStream sis = socket.getInputStream();
        DataInputStream dis = new DataInputStream(new BufferedInputStream(sis));
        long size = dis.readLong();
        int count;
        log ("Receiving file");
        while (size > 0 && (count = dis.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
            fos.write(buffer, 0, count);
            size = size - count;
        }
        fos.close();
        log ("File received");
        String s;
        while ((s = dis.readUTF()) != null) {
            log(s);
        }

The Song is successfully received but after that no communication with the socket is possible! I have tried different ways - PrintWriter, write(bytes[]). Nothing happens - the client side code does not enter the second while loop.

I don't understand what wrong I'm doing.

bradley101
  • 723
  • 6
  • 19
  • Do you close the `socketOutputStream`? If not, how would `readUTF()` know whether you're going to send more data, and are just being very slow at it? – Andreas Jan 08 '17 at 06:08
  • Can you explain your comment? – bradley101 Jan 08 '17 at 06:10
  • 1
    Hmmm... Sorry, I'm likely right while also being wrong. The server doesn't close the stream, so no end-of-stream signal is sent to the client, and it will simply sit there and wait for more data. But, where did you get the idea that [`readUTF()`](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#readUTF--) would return `null`? The javadoc doesn't say that's possible. It actually says that end-of-stream will cause `EOFException` instead. Since you don't get that either, my first observation seems true: The method is waiting for more data. – Andreas Jan 08 '17 at 06:19
  • 1
    It has to sit for more data. The songFile earlier is sent successfully and the client also logs "File Received", so after that it reads more data, and server is providing it with more data. What's the problem? – bradley101 Jan 08 '17 at 06:26
  • If I close the stream by `shutdownOutput()` it can never be opened! – bradley101 Jan 08 '17 at 06:27
  • You don't flush after calling `writeUTF("play")`. You never write anything else (in code shown), so ... `readUTF()` is waiting... waiting... waiting... waiting... waiting... waiting... waiting... waiting... waiting... waiting... waiting... waiting... BTW: You should call `flush()` on `socketDataOutputStream`, not `socketOutputStream`. – Andreas Jan 08 '17 at 06:30
  • 1
    @Andreas He doesn't have to flush anything unless there is a `BufferedOutputStream` in the stack. – user207421 Jan 08 '17 at 06:45
  • @andreas you were right! I added `socketDataOutputStream.flush()` and it worked! Client received "play" string! You made my day! Post it as the answer so that I can accept it! – bradley101 Jan 08 '17 at 07:01

1 Answers1

3
while ((s = dis.readUTF()) != null) {
        log(s);

Remove this. It doesn't make sense. readUTF() doesn't return null, and you shouldn't be just throwing input away.

If this is supposed to be receiving the "play" command, you should store one readUTF() result into a String and then compare it to "play" properly. But the command is redundant. You can play it as soon as you've finished receiving it, and you know when that is.

The sleep is literally a waste of time. Remove that too.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • @andreas has solved the issue! Thanks a lot! – bradley101 Jan 08 '17 at 07:02
  • 2
    He's solved part of it, and the necessity for the `flush()` isn't apparent in the code you posted. The loop above is still wrong and needs removal or remedying as per above, and the sleep is still a waste of time. – user207421 Jan 08 '17 at 07:16
  • so I write the `s = dis.readUTF()` inside a `while(true)` and check if it is equal to "play" or something else. right? – bradley101 Jan 08 '17 at 07:22
  • No. Read what I wrote. I said to *remove* the loop, and to use *one* `readUTF()` call. – user207421 Jan 08 '17 at 07:43
  • Yes I've got what you are using, I have to write multiple data to the Client side. That's why I inserted a loop. Thanks! – bradley101 Jan 08 '17 at 08:03
  • 2
    If you're going to throw away whatever is written, you didn't need to write it in the first place. You inserted the loop because you couldn't be bothered to implement your application protocol properly. – user207421 Jan 08 '17 at 09:09