[erlang-questions] How to write a TCP server in Erlang?

Ulf Wiger ulf@REDACTED
Thu Jun 14 22:43:44 CEST 2007


I venture a guess that you send the second message from the
client and then call gen_tcp:close(Sock). Is that right?

Since you have no flow control between the client and server,
the client will fire off its messages and then close the socket
while the server is busy writing the results of the first message
to the tty.

If you e.g. insert a timer:sleep(500) between the sends on
the client side, things will likely work. You could of course also
have the client wait for a reply from the server. (:

Oh, and you should call gen_tcp:controlling_process(Sock, Worker)
on the server side. It doesn't matter in this limited example, since
you explicitly do receive on a passive socket, but it's still the
right thing to do, I think.

BR,
Ulf W

2007/6/14, Matej Kosik <kosik@REDACTED>:
> Hello,
>
> Can somebody recommend me some great tutorials on TCP servers (and clients) written in Erlang? The reference manual is quite clear, however according to that information I am failing to implement what I need (I am ashamed).
>
> The attached code works. A single packet is successfully transmitted from the client to the server. However, if I try to send another packet, the `recv' operation at server side instead of returning
>
>         {ok, SomeBinaryData}
>
> Returns
>
>         {error,closed}
>
> That is, the socket gets closed immediatelly after the first receive.
>
> How to do these two transmissions correctly? For example, how to write a simple TCP server that for each connected client acts as an echo server (i.e. it sends back what it received)?
>
> Thank you very much for any kind of helpful pointers.
>
> Regards
> --
> Matej Kosik
>
> % Ked sa server pusti na altairi a klient na notebook-u, tak toto v celku pekne funguje. Klienta je mozne spustit viackrat. Zakazdym sa ale fork-ne iny worker.
>
> -module(server).
> -export([start/0, worker/1]).
>
> start() ->
>   {ok, LSock} = gen_tcp:listen(2000, [binary, {packet, 0}, {active, false}]),
>   server(LSock).
>
> server(LSock) ->
>   {ok, Sock} = gen_tcp:accept(LSock),
>   spawn(?MODULE, worker, [Sock]),
>   server(LSock).
>
> % This process is responsible for handling single client.
> worker(Sock) ->
>   {ok, Bin} = gen_tcp:recv(Sock, 0),
>   {Num1, Num2} = binary_to_term(Bin),
>   io:format("numbers: ~w ~w~n", [Num1, Num2]),
>   io:format("sum: ~w~n", [Num1+Num2]),
>   gen_tcp:close(Sock).
>
> -module(client).
> -export([start/0]).
>
> start() ->
>     SomeHostInNet = "localhost",
>     %SomeHostInNet = {127, 0, 0, 1},
>     %SomeHostInNet = {147, 175, 98, 6},
>     {ok, Sock} = gen_tcp:connect(SomeHostInNet, 2000, [binary, {packet, 0}, {active, false}]),
>     ok = gen_tcp:send(Sock, term_to_binary({30, 40})),
>     ok = gen_tcp:close(Sock).
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
>



More information about the erlang-questions mailing list