[erlang-questions] gen_tcp very slow to fetch data
ERLANG
erlangy@REDACTED
Mon Nov 16 18:59:39 CET 2009
Hi Chandru !
That's fix my problem. Thanks.
While googling a bit, I found two ways to read from the Socket:
recv(Socket, Bin) ->
receive
{tcp, Socket, B} ->
io:format(".", []),
recv(Socket, concat_binary([Bin, B]));
{tcp_closed, Socket} ->
{ok, Bin};
Other ->
{error, {socket, Other}}
after
?TIMEOUT ->
{error, {socket, timeout}}
end.
% version 2 with "gen_tcp:recv"
recv2(Socket, Bin) ->
case gen_tcp:recv(Socket, 0, ?TIMEOUT) of
{ok, B} ->
io:format(".", []),
recv(Socket, concat_binary([Bin, B]));
{error, closed} ->
{ok, Bin};
{error, timeout} ->
{error, {socket, timeout}};
Other ->
{error, {socket, Other}}
end.
Which one is the best in my case (see below: fetch.erl)?
Regards
Zabrane
Le 16 nov. 09 à 18:53, Chandru a écrit :
> You are expecting the server to indicate end of response by closing
> the
> connection, but because you specify HTTP/1.1 in the request, the
> server is
> holding up your connection, and you are timing out. Try replacing
> HTTP/1.1
> with HTTP/1.0 in your request, or parse the response to detect end of
> response.
>
> cheers
> Chandru
>
> 2009/11/16 zabrane Mikael <zabrane3@REDACTED>
>
>> Hi List !
>>
>> New to Erlang, I'm trying to implement a simple URL fetcher.
>> Here's my code (please, feel free to correct it if you find any bug
>> or know
>> a better approach):
>>
>>
>> 8
>> -----8
>> -----8
>> -----8-----8-----8-----8-----8-----8-----8-----8-----8-----8----
>> -module(fetch).
>>
>> -export([url/1]).
>>
>> -define(TIMEOUT, 7000).
>> -define(TCP_OPTS, [binary, {packet, raw}, {nodelay, true},
>> {active, true}]).
>>
>> url(Url) ->
>> {ok, _Tag, Host, Port} = split_url(Url),
>>
>> Hdrs = [],
>> Request = ["GET ", Url, " HTTP/1.1\r\n", Hdrs, "\r\n\r\n"],
>>
>> case catch gen_tcp:connect(Host, Port, ?TCP_OPTS) of
>> {'EXIT', Why} ->
>> {error, {socket_exit, Why}};
>> {error, Why} ->
>> {error, {socket_error, Why}};
>> {ok, Socket} ->
>> gen_tcp:send(Socket, list_to_binary(Request)),
>> recv(Socket, list_to_binary([]))
>> end.
>>
>> recv(Socket, Bin) ->
>> receive
>> {tcp, Socket, B} ->
>> io:format(".", []),
>> recv(Socket, concat_binary([Bin, B]));
>> {tcp_closed, Socket} ->
>> {ok, Bin};
>> Other ->
>> {error, {socket, Other}}
>> after
>> ?TIMEOUT ->
>> {error, {socket, timeout}}
>> end.
>>
>>
>> split_url([$h,$t,$t,$p,$:,$/,$/|T]) -> split_url(http, T);
>> split_url(_X) -> {error, split_url}.
>>
>> split_url(Tag, X) ->
>> case string:chr(X, $:) of
>> 0 ->
>> Port = 80,
>> case string:chr(X,$/) of
>> 0 ->
>> {ok, Tag, X, Port};
>> N ->
>> Site = string:substr(X,1,N-1),
>> {ok, Tag, Site, Port}
>> end;
>> N1 ->
>> case string:chr(X,$/) of
>> 0 ->
>> error;
>> N2 ->
>> PortStr = string:substr(X,N1+1, N2-N1-1),
>> case catch list_to_integer(PortStr) of
>> {'EXIT', _} ->
>> {error, port_number};
>> Port ->
>> Site = string:substr(X,1,N1-1),
>> {ok, Tag, Site, Port}
>> end
>> end
>> end.
>>
>>
>> 8
>> -----8
>> -----8
>> -----8-----8-----8-----8-----8-----8-----8-----8-----8-----8------
>>
>> When testing it, the receiving socket gets very very slow:
>> $ erl
>> 1> c(fetch).
>> 2> Bin = fetch:url("http://www.google.com").
>> ......{error,{socket,timeout}}
>>
>> Am I missing something?
>> What I like to get at the end is a very fast fetcher. Any hint?
>>
>> Regards
>> Zabrane
>>
More information about the erlang-questions
mailing list