Messages using gen_tcp:send doesn't get sent until the socket is closed
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 th开发者_开发问答at 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.
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
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").
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.
精彩评论