This line because you are trying to allocate the entire stream into RAM.
byte[] receivedData = new byte[dataLength];
When your stream is small, it is OK. But for big streams, allocate a small buffer (eg. 10K) and read it in chunks.
@nos also gave a comment about server writing the file name first, followed by the file length. You have to read it in the order that the data is written. But even after you read in the correct data, you will eventually have the problem I described. You definitely need to read data in chunks and process it as you go.
In addition, since you are sending the file name to the receiver, it is good to define a proper structure/header/protocol so that the receiver can easily process the incoming data. Here is a suggestion.
- 1 byte to denote the file name length
- following bytes are the actual file name
- 8 bytes to denote length of contents of file.
- following bytes are contents of file.
At the receiver end, you read first byte to know how many bytes to read for the file name. Then you read 8 bytes to know how many bytes to read for the contents.