it reads way less than half the file size sent from the client. I dont know why.
This one is easy. Remember the network code splits your big data block into a lot of small packets and sends each of them to the other side?
These packets do not arrive all at the same time, so if you read at the other side, and a bunch arrives, the kernel gives you what it received so far, up to the length you requested. Normally, it is less than what you asked for, unless you start asking for a single byte or so. In any case, your local processing is always faster than the network, so at some point you'll run out of received bytes, and you have to wait again for more.
You may think the stream is "<number>" "\n" "<data>" but to the application it is one long stream of bytes without any separation markers whatsoever. Data doesn't arrive in blocks as you wrote it. Big blocks get split, smaller blocks may get merged before sending. It is totally feasible that the receiving end gets "<number>\n<d" and "ata>" or it might get "<numb", "er", ">\n<dat", and "a>", or some other random split on the stream in small packets.
As for not getting more after that, until you proof otherwise, my guess is that your buffered io wrappers for reading the number are eating some of your file data. Don't read from different levels of io layers from a single source, it's not reliable. Lower layers may optimize performance by reading more than needed at higher level etc.
And then the second read() blocks forever. This happens only when I try to read the same file save at the current server run time. As described in the first post - when I read a previously saved file even at the current server in real time, it work fine , but then even this also blocks at times. If you think what i'm writing deosn't make any sense, you're very correct because it really makes no sense.
After reading the InputStream.read description, and your buffer loop reader, it starts to make sense, but it's a few steps before you arrive there.
The first thing what you must do is to stop using code that you do not fully understand. If you don't entirely understand your "read buffer" loop code, you're coding the higher levels on top of "I think it might do X", for some unknown value of X. Together with the inherently random nature of network IO wrt timing, speed, and bandwidth, you get what you experience, seemingly random behavior that works and then breaks again.
The only way forward is to exactly know what X is. You do that by writing your own "read buffer" loop from the InputStream.read documentation. That way, you know the purpose of each and every statement, you know exactly what to expect from that low level function, and you can stack the higher level code on top of known functionality.
So as homework, I'd suggest you write your own "read data into buffer" loop, using only the description of InputStream.read. Afterwards, compare notes, where does your implementation work differently from the $random website one? My guess is you'll do the "-1" case differently, in particular, after receiving all data that you need.
The second thing you must do is to stop thinking in server-only and client-only. It seems to me you're coding a server, and you;re coding a client, then run them both and hope it works. In networking, failure and blocking can have 3 causes. A) Server code can be wrong, B) Client code can be wrong, C) Either side can get blocked or die or whatever, due to things that the other side does or does not do. The 3rd item is what is causing your blocking.
To get a handle on this, you can draw the interactions between the server and the client with a message sequence chart
https://en.wikipedia.org/wiki/Message_Sequence_Chart
That page has a lot more stuff than you need though. Basically, you draw two vertical lines next to each other, one is labeled "server" and the other is labeleled "client". Time increases vertically down. With arrows from one line to the other, you can show what messages (what data) you send from one end to the other. I'd start after accepting the connection, and up to and including closing the connection (since it's a relevant event that you send by closing the socket, and that you receive with the -1 return value from read).
You'll end up with some horizontal arrows from the client to the server (server receiving length and the file), and then some arrows from client to server (client receiving length and the file), and then 'close connection' arrows at the end. Technically, the arrows are not horizontal (network transfer takes time), but you're not interested in precise timing, just order of messages being exchanged.
If all is well, at this point, you understand that the "-1" case in the google code waits for closing the connection. Relate that to the diagram, and you'll find how things block indefinitely.
So with this way, will I have to write a little function -> read_byte()?
It's the elementary InputStream.read function, except for the closed-connection case. I had hoped you'd understand that, but I guessed wrong.
Note this is also $random website code, which above I said you shouldn't use without understanding. Analyze it, and understand how and why it works. Then rebuild it. Know X, instead of guessing what X might be.