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:recv apparently has no knowledge of when a "complete" message from the client has been received, and is therefore "splitting" it up in multiple messages.
This is an example of what I'm doing (Incomplete code, trying to keep it to only the relevant parts):
Code
Erlang server
-module(server).
-export([start/1]).
-define(TCP_OPTIONS, [list, {packet, 0}, {active, false}, {reuseaddr, true}].
start(Port) ->
{ok, ListenSocket} = gen_tcp:listen(Port, ?TCP_OPTIONS),
accept(ListenSocket).
accept(ListenSocket) ->
{ok, Socket} = gen_tcp:accept(ListenSocket),
spawn(fun() -> loop(Socket) end),
accept(ListenSocket).
loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
io:format("Recieved: ~s~n", [Data]),
loop(Socket);
{error, closed} ->
ok
end.
Java client
public class Client {
public static void main(String[] args) {
Socket connection = new Socket("localhost", Port);
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
Scanner sc = new Scanner(System.in);
while(true) {
output.writeBytes(sc.nextLine());
}
}
}
Result
Client
Hello!
Server
Received: H
Received: el
Received: lo!
I have been searching around and if I understand it correctly, TCP has no knowledge of the size of messages, and you need to manually set some kind of delimiter.
What I don't get though, is that the messages never seem to split up if I write the client in Erlang instead, like this:
Erlang client
-module(client).
-export([start/1]).
start(Port) ->
{ok, Socket} = gen_tcp:connect({127,0,0,1}, Port, []),
loop(Socket).
loop(Socket) ->
gen_tcp:send(Socket, io:get_line("> ")),
loop(Socket).
Result
Client
Hello!
Server
Received: Hello!
This makes me wonder if it is something that can be fixed on the Java side? I have tried several combinations of different output streams, write methods and socket settings on the server side, but nothing solves the problem.
Also, there are loads of Erlang (chat) server examples around the net where they don't do any delimiter things, although those are often written in Erlang on both ends. Nevertheless, they seem to assume that the messages are received just like they are sent. Is that just bad practice, or is there some hidden information about message length when both the client and server are written in Erlang?
If delimiter checks are necessary, I am surprised I can't find much information on the subject. How can it be done in a practical way?
Thanks in advance!
See Question&Answers more detail:
os