1

I want to write a simple client that sends a message to a server and receives a response. I've got a server that broadcasts the same message to all connected clients and its working when I'm testing it with telnet. When I try doing it using the Erlang shell, gen_tcp:send wont send any messages until I've close the socket.

This is what I'm trying to do:

{ok, S} = gen_tcp:connect(IP, Port, []).
gen_tcp:send(S, "Test").
flush().

I can see that the message gets sent when I close the socket by looking at my telnet client.

Erlang version:R14B01 (erts-5.8.2)

Update

hdima commented and said that it might be wrong with how the server extract the messages from the stream. This seems to be the case cause when I tried writing my own server the client seems to work as expected. I'll try to get the source code of the server. The server is written in Java btw.

softarn
  • 5,327
  • 3
  • 40
  • 54

3 Answers3

4

When sending small chunks of data the socket buffers them up to try to fill up the maximum payload for a TCP packet.

It is possible that this is what is going on because when you close the socket it is flushed before it is deallocated.

Try setting the

{nodelay, true}

option on your socket.

More info here: http://www.erlang.org/doc/man/inet.html#setopts-2

Mazen Harake
  • 1,706
  • 1
  • 11
  • 17
  • 1
    This is the best answer. The client is buffering the data. It has nothing to do with the server. The crucial setting is {packet, PacketType}, which is explained in the section that you linked to. – Nate C-K Jul 05 '12 at 19:35
3

The main problem is that there is no Universal Message Format. So your first step is to find what message format the server using. You can't speak with the server on a different language.

Some message formats can be:

  • The whole stream is a message.
  • Fixed size messages.
  • Messages delimited by a marker. For example SMTP, POP, HTTP and many other protocols use this type of messages.
  • Messages with a size field. For example TLV (Type-Length-Value) message format. IP, UDP, Erlang and many other protocols use this type of messages.

For example if the server understand messages delimited by the line feed character you can send two distinct messages with the following code:

1> {ok, S} = gen_tcp:connect(IP, Port, []).
2> gen_tcp:send(S, "Test\n").
3> gen_tcp:send(S, "Test2\n").
hdima
  • 3,627
  • 1
  • 19
  • 19
  • Sending messages with the line ending works. The java server is probably using readLine() or similar. Thank you! – softarn Sep 12 '11 at 12:59
  • I don't think this is correct. This has nothing to do with the type of messages that the server expects. It is due to the socket settings on the Erlang side. Use the {packet, PacketType} setting to configure this. – Nate C-K Jul 05 '12 at 19:37
  • @NateC-K With {packet, PacketType} option Erlang just send/receive every message as Length-Value transparently for you. You must understand the message format if you plan to connect with servers/clients written in other languages, like Java in the question. – hdima Jul 06 '12 at 14:03
1

You can try this out with an Erlang server to see if it is the server or client side that has problems.

In shell A:

1> {ok, L} = gen_tcp:listen(12345, [{active, false}]).
{ok,#Port<0.601>}
2> {ok, S} = gen_tcp:accept(L), {ok, P} = gen_tcp:recv(S, 0), gen_tcp:send(S, P).
... % Server will block here until a message comes
ok

In shell B:

1> {ok, S} = gen_tcp:connect(localhost, 12345, []), gen_tcp:send(S, "hello").
ok
2> flush().
Shell got {tcp,#Port<0.607>,"hello"}

If this works, it's most likely a problem on the Java side.

Adam Lindberg
  • 16,447
  • 6
  • 65
  • 85
  • If you read the update part I've already stated that it seems to be the server. But thank you for taking time and answering! – softarn Sep 09 '11 at 13:37
  • Ah, didn't spot that. :-) You can answer your own question as well, and mark that answer as accepted. – Adam Lindberg Sep 09 '11 at 15:08
  • My question is almost answered, but I want to find out what's wrong with the java code before I mark anything as correct. – softarn Sep 09 '11 at 18:56