-1

I read most of SO answers and couldn't find why readUTF() hangs. The code is so generic, but this somehow hangs.

Client side:

int ip = "192.168.56.101"
String filepath = "your local file path" // pdf file works, mp3 or mp4 don't work
int port = 6000;
int port1 = 6001;
Socket socket = new Socket(ip, port);
Socket socket1 = new Socket(ip, port1);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket1.getOutputStream());
String filename = "filename_doesnt_matter_but_file_type_matters";

dos.writeUTF(filename);                  // USED writeUTF()
dos.flush();  dos.close();  socket.close();
FileInputStream fis = new FileInputStream(new File(filepath));
BufferedInputStream bis = new BufferedInputStream(fis);
final byte[] bytearray = new byte[(int) fis.length()];
bis.read(bytearray, 0, bytearray.length);
oos.writeObject(bytearray);              // THIS WRITES THE FILE
oos.flush();  oos.close();  socket1.close();

Server side:

int port = 6000;
int port1 = 6001;
ServerSocket ss = new ServerSocket(port);
ServerSocket ss1 = new ServerSocket(port1);
Socket socket = ss.accept();
Socket socket1 = ss1.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
ObjectInputStream ois = new ObjectInputStream(socket1.getInputStream());

FileOutputStream fos = new FileOutputStream(new File("local path where I save my file"));
ois = new ObjectInputStream(socket1.getInputStream());
final BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytearray = (byte[]) ois.readObject();
bos.write(bytearray);
bos.flush();
String filename = dis.readUTF();   <----- HANGS HERE

Filename is very small that size is not an issue. What could be a possible problem?

Edit: Forgot to mention that this reads filename "Dummy1.pdf" but doesn't read something like "mp4" or "file_dummy.mp3" I still have no idea when it can read and when it hangs... I tried ObjectOutputStream instead of DataOutputStream and tried writeObject(filename) as well, but it still doesn't read. I also tried wrapping BufferedInputStream as suggested, which didn't work as well...

NEW EDIT: I figured out when it hangs. It hangs when I try to transfer an mp3 or mp4 file. When I transfer a pdf file, the filename of the file is transferred. However, when I try to transfer an audio or a video file, the file is transferred but the filename is not (code hangs at readUTF(). If I comment it out, then I receive the file)..

lollip0o0p
  • 105
  • 1
  • 1
  • 7
  • 2
    Looks OK to me, as `writeUTF()` is guaranteed to write out data that `readUTF()` can read. Are you sure your client is the correct one actually being `accept()`'ed, and not some other app that happened to find your server? Have you sniffed the network traffic to see what the client is actually transmitting and what the server is actually receiving? Have you tried using a `BufferedInputStream` as the input for the `DataInputStream`? – Remy Lebeau Jul 14 '20 at 19:05
  • @remyLebeau I'm 100% sure the client is the only one being accepted. I actually transfer files as well through different ports, and they seem to have no problem. Can bufferedinputstream do writeUTF() as well? – lollip0o0p Jul 14 '20 at 20:01
  • 1
    I tried the code and it works for me. On your client side, you create the variable filename but no value is assigned. Are you sure the string contains something meaningful? – vanje Jul 14 '20 at 20:07
  • @vanje even if `filename` were blank, `writeUTF()` would still transmit the byte length of the string (0), and then `readUTF()` would read that length and return a blank string. – Remy Lebeau Jul 14 '20 at 20:12
  • Maybe your filename is null and you omit the exception? Or is there a firewall between? Do you run client and server on the same machine? – vanje Jul 14 '20 at 20:16
  • 2
    @JunepyoLee using a `BufferedInputStream` is usually the preferred way to handle inbound bytes on a streaming `Socket`. It allows more efficient reading, by extracting more bytes at a time from the socket and buffering them in the app's memory. The `DataInputStream` doesn't care where the bytes actually come from, it is just going to read individual bytes from whatever input stream is assigned to it. So better for it to read individual bytes from memory than from the socket directly. The sooner that bytes can be emptied from the socket, the better throughput it can reach. – Remy Lebeau Jul 14 '20 at 20:17
  • 1
    @vanje that is a good point about `filename` being `null`, since `writeUTF()` is defined to throw `NullPointerException` on `null` input. However, a firewall would not cause the behavior the OP is seeing (a firewall blocks connections, not data), and neither would client and server being on the same machine, either (TCP doesn't care about that). – Remy Lebeau Jul 14 '20 at 20:22
  • @vanje yes filename contains the actual filename. It's never null. – lollip0o0p Jul 14 '20 at 20:51
  • @RemyLebeau Should I wrap DataInputStream with BufferedInputStream or only use BufferedInputStream? I am going to try this: https://stackoverflow.com/questions/5713857/bufferedinputstream-to-string-conversion – lollip0o0p Jul 14 '20 at 20:54
  • 1
    @JunepyoLee `DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));` I'm not saying this will *definitely* solve your hang issue, but it is something you should do in general anyway. – Remy Lebeau Jul 14 '20 at 20:59
  • @RemyLebeau It is still hang at `dis.readUTF()` even though I wrapped `BufferedInputStream` with `DataInputStream()`. Also, it reads something like "Dummy1.pdf", but doesn't read other strings like "file_dummy.mp4" or even "mp4" I have no idea when it can read and when it hangs... – lollip0o0p Jul 14 '20 at 21:21
  • 1
    @JunepyoLee You still haven't answered my other, more important, question - "*Have you sniffed the network traffic to see what the client is actually transmitting and what the server is actually receiving?*". Can you *verify* that your client is actually transmitting data? Also, can you please [edit] your question to reformat your example into a [mcve]? – Remy Lebeau Jul 14 '20 at 21:40
  • @RemyLebeau How do I sniff the network traffic? Also, I thought my example was minimal reproducible... – lollip0o0p Jul 14 '20 at 21:48
  • 1
    @JunepyoLee Use a packet sniffer such as [Wireshark](https://www.wireshark.org/). And no, you example is not *minimal* reproducible. There is no program entry point. The `ip` and `port` variables are not declared and initialized. The `filename` is not initialized. Part of a [mcve] is for people to be able to copy/paste, COMPILE, and RUN the example on their systems to verify the troublesome behavior happens for them, too. One commenter already stated the code works for them, so your problem is clearly not reproducible as currently shown. There must be a missing detail you haven't provided yet – Remy Lebeau Jul 14 '20 at 21:54
  • 1
    @JunepyoLee Your edit is still not a [mcve]. However, case in point about missing details - you state that your server IP is a "bridged adapter on my VM". You didn't say before that you were running code inside a VM. That is an important detail. Are both client and server running inside the same VM? Or are they both running in separate VMs on the same bridge? Or is one of them running on the VM Host? Are you sure the VM's networking bridge is even configured properly? Do you have other networking apps that can communicate with each other without trouble? These are important details to verify. – Remy Lebeau Jul 14 '20 at 21:58
  • @RemyLebeau no other networking apps that can cause issues. I tried just on my windows as well and didn't work, so I didn't put that description there before. I have two other socket connections than this that transfers other objects to test if they are transferred properly. One is a bytearray and the other is a file. Both of them are transmitted properly, so I didn't think the network would be the issue. – lollip0o0p Jul 14 '20 at 22:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/217848/discussion-between-remy-lebeau-and-junepyo-lee). – Remy Lebeau Jul 14 '20 at 22:06
  • You don't need all this complication, with two sockets per file. Use the code in my answer in the duplicate, using one socket for as many files as you like. – user207421 Jul 16 '20 at 00:09

1 Answers1

0

So... I tried this and works. Instead of creating multiple sockets with multiple ports, I write the filename and the file both on ObjectOutputStream oos.

oos.writeUTF(filename)
oos.writeObject(bytearray)

Then, on the client, I simply read the filename with readUTF() and read the file with readObject() and it works.

lollip0o0p
  • 105
  • 1
  • 1
  • 7