As the title says, I have a server written in Erlang, a client written in Java and they are communicating through TCP. The problem that I am facing is the fact that gen_tcp:
You need to define a protocol between your server and your client to split the TCP stream into messages. TCP stream is divided in packets, but there is no guarantee that these match your calls to send/write or recv/read.
A simple and robust solution is to prefix all messages with a length. Erlang can do this transparently with {packet, 1|2|4}
option, where the prefix is encoded on 1, 2 or 4 bytes. You will have to perform the encoding on the Java side. If you opt for 2 or 4 bytes, please be aware that the length should be encoded in big-endian format, the same byte-order used by DataOutputStream.outputShort(int)
and DataOutputStream.outputInt(int)
java methods.
However, it seems from your implementations that you do have an implicit protocol: you want the server to process each line separately.
This is fortunately also handled transparently by Erlang. You simply need to pass {packet, line}
option. You might need to adjust the receive buffer, however, as lines longer that this buffer will be truncated. This can be done with {recbuf, N}
option.
So just redefining your options should do what you want.
-define(MAX_LINE_SIZE, 512).
-define(TCP_OPTIONS, [list, {packet, line}, {active, false}, {reuseaddr, true}, {recbuf, ?MAX_LINE_SIZE}].