If you don't close the writing end of the connection and keep it fully open, then, unless the server knows in advance the size of the file it is to receive (or that size, or information as to where the file ends, is somehow embedded in the contents of the file), it will have no way to know where the end of the file is.
The default modus operandi of socat is upon eof on the first address to shut the writing side of the other address down (so the other end knows you've finished sending), wait for the -t timeout for the other end to close and then terminate, which is likely what you want here, increasing the timeout to the maximum time you're willing to wait for that answer. So:
socat -t3600 -<file.bin tcp:server:1234
Using - (short for STDIO) which means stdin (here redirected to file.bin) is sent and the server's response goes to stdout, and waiting for up to one hour for the response.
You can test with localhost as the server by running:
socat -t3600 tcp-listen:1234,fork,reuseaddr 'system:"
cat > file.out || exit; sleep 5; echo OK"'
For the server part in another terminal.
Then:
$ time socat -t3600 -<file.in tcp:localhost:1234
OK
socat -t3600 - tcp:localhost:1234 < file.in 0.00s user 0.01s system 0% cpu 5.012 total
Got the expected OK response after 5 seconds, the time it took for the server to send it (here arbitrarily delayed with that sleep 5 for demonstration).
Note that it does not guarantee that if you get a OK, the file has been correctly sent, without alteration, in full and to the right machine. For that, you'd need a protocol that gives those guarantees such as ssh:
if <file.in ssh hostname 'cat > file.out && echo OK'; then
echo the file has been successfully received
fi
Using a compressor with its own integrity check can even improve it on the off chance that some glitch in the ssh protocol handling causes the file not to be fully sent while the response manages somehow to make it back to the client:
if <file.in gzip | ssh hostname 'gunzip > file.out && echo OK'; then
echo the file has been successfully received
fi
(note the echo OK is not even necessary (and ignored anyway here) as ssh transmits the exit status of the command back, which is what we rely on here).
C,Perl,Rust, etc).expectand friends are for: open a connection to something, wait for a short time or for a known prompt, send whatever, wait for a response & do something with it. They're often used to wait for and respond to login and password prompts, but aren' limited to that. One other alternative if your tcp server on port 1234 uses some well-known protocol, there's a small chance that perl has a library that speaks it. And python might too.expect-- at least -- connects to a process/program that does I/O over a TTY (by giving it a PTY instead); a socket isn't a TTY and isn't even a first-class file although some shells, and gawk, make it partly work like one