[erlang-questions] gen_tcp and processes receiving

James Cone jcone@REDACTED
Fri Oct 5 07:44:38 CEST 2007


Message-ID: <20071004191041.GA17261@REDACTED>

Hello Stephan, et al,

I don't know how to reply to a digest message; please accept my 
apologies if this reply is not joined on.  I am using Thunderbird, and 
am open to suggestions by email.

I have got Stephan's code to work.  The whole code is below.  I made the 
following gratuitous changes:
   - make the host to connect to into a parameter

I had to make the following changes:
   - add {packet, raw} to the connect options
       - vaguely explained under recv on the gen_tcp page
       - explained better on the inet page

   - use the beginners' syntax for spawn_link
       - I have no idea why this is important, but I couldn't get the 
other one to go

   - complete the loops in doListen and receiver
       - just to get all of the characters

   - remove the io:format from doListen
       - there seems to be locking in the io, so that io from receiver 
can cause starvation in doListen

The code has the following remaining problems:
   - receiver ends disgracefully, when the other end closes the socket 
(trivial)

   - when receiver ends, it takes out doListen, so some of the received 
characters may not be processed

I am confused about Stephan's goal, and whether one byte is an 
appropriate buffer size; it may be for demonstration purposes only.

I am confused about whether there is a better way (documented in inet or 
somewhere) of causing TCP flow-control on the socket.

Regards,
James.

=======================================

-module(tcp_ebadf).

-export([start/1, receiverStart/2]).


start(Host) ->
     io:format("Connecting...~n"),
     {ok, Socket} = gen_tcp:connect(Host, 80,
                                    [{active, false}, {packet, raw}]),

     io:format("Sending...~n"),
     gen_tcp:send(Socket, "GET / HTTP/1.1\r\n"
                  "Host: www.erlang.org\r\n"
                  "Connection: close\r\n"
                  "\r\n"),

     Pid = spawn_link(?MODULE, receiverStart, [self(), Socket]),

%    Pid = spawn_link(fun() ->
%                            receive
%                                go ->
%                                    ok
%                            end,
%                            receiver(self(), Socket)
%                    end),
     ok = gen_tcp:controlling_process(Socket, Pid),
     Pid ! go,

     io:format("Waiting...~n"),
     doListen(Socket).

doListen(Socket) ->
     receive
         {byte, _B} ->
             io:format("Ok, I received a byte: ~p ~n", [[_B]])
     after 10000 ->
             gen_tcp:close(Socket),
             exit(timeout)
     end,
     doListen(Socket).


receiverStart(Listener, Socket) ->
     io:format("Starting with ~w, ~w~n", [Listener, Socket]),
     receive
       go -> ok
     end,
     receiver(Listener, Socket).

receiver(Listener, Socket) ->
%    io:format("Receiving...~n"),
     {ok, [B]} = gen_tcp:recv(Socket, 1),
     Listener ! {byte, B},
     receiver(Listener, Socket).



More information about the erlang-questions mailing list