Using TCP sockets with 'receive' instead 'gen_tcp:recv/2'
Jérémie Lumbroso
jeremie@REDACTED
Sun Mar 26 16:01:17 CEST 2006
Hello,
To get to know Erlang, and how to use it, I've set myself a small
introductory project. So for this first project, I wanted to write a
Clue[do] server. But I've encountered a serious problem with the receive ...
after ... end construct. I would like to use it to handle the client sockets
which were obtained using gen_tcp:accept/1, and for that purpose, have made
sure to set the option {active, true} wherever I thought it mattered. But it
still does not work—and I have no idea why.
This is the code that I use to create the listening socket:
gen_tcp:listen(?port, [binary,
{nodelay, true},
{packet, 0},
{reuseaddr, true},
{active, false}])
And here is how I accept the client sockets:
server_accept(LSock, User_List) ->
case gen_tcp:accept(LSock, 1000) of
%%%%
% Spawning a new thread, linking to it, and returning
% a new 'user list'.
{ok, Sock} ->
io:format("Client connected successfully ...~n"),
Pid = spawn_link(?MODULE, relay, [Sock]),
Client = #client{pid = Pid, socket = Sock},
[ Client | User_List ];
_Else ->
User_List
end.
And finally, here is the relay function in question (BTW, the documentation
says that I can't use the receive to figure out when a socket created with
accept is closed, but I was not sure if this was an omission or an actual
limitation):
relay(Socket) ->
io:format("[debug]-> start~n"),
%%%% Activate socket (so we can receive through it.
inet:setopts(Socket, [binary, {nodelay,true},
{active, true}]),
relay(Socket, []).
relay(Socket, Buffer) ->
receive
%%%%
% Split the received data in lines, process them
% and put the extra data back in buffer before
% starting the loop again.
{tcp, Socket, Bin} ->
Data = binary_to_list(Bin),
io:format("[debug]-> ~p~n", [ Data ]),
case regexp:split(Buffer ++ Data, "\r\n") of
{ok, FieldList} ->
New_Buffer = process_lines(FieldList);
_NoMatch ->
New_Buffer = Buffer ++ Data
end,
?MODULE:relay(Socket, New_Buffer);
{tcp_closed, Socket} ->
io:format("[debug]-> end"),
exit(self(), tcp_closed);
{server, close} ->
gen_tcp:close(Socket),
exit(self(), tcp_closed);
{server, {data, Data}} ->
gen_tcp:send(Socket, Data),
?MODULE:relay(Socket, Buffer)
after
5000 ->
io:format("[debug]-> wait~n"),
?MODULE:relay(Socket, Buffer)
end.
In case this is not enough, I've attached the whole file as well.
Is there something that I'm doing wrong or is this just how it (doesn't)
work?
Best Regards,
- Jérémie Lumbroso
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20060326/2b17f0b6/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: snippet.erl
Type: application/octet-stream
Size: 3428 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20060326/2b17f0b6/attachment.obj>
More information about the erlang-questions
mailing list