Я написал простой http-клиент и столкнулся со следующей проблемой: я скопировал это do_recv
из официального документа, но он работает странным образом:
do_recv(Sock, Bs) ->
case gen_tcp:recv(Sock, 0, ?TIMEOUT) of
{ok, B} ->
gen_tcp:shutdown(Sock, write), % <-- this appears to fix the problem!
do_recv(Sock, [Bs, B]);
{error, closed} ->
{ok, list_to_binary(Bs)}
end.
Последовательность чата следующая:
{ok, S} = gen_tcp:connect(Ip, Port, [inet, binary,
{packet, 0},
{active, false},
{nodelay, true},
{reuseaddr, true}], 2000),
Req = io_lib:format("GET ~s HTTP/1.1\r\nHost: ~s\r\n\r\n", [Url, UrlHost]),
ok = gen_tcp:send(S, list_to_binary(Req)) of
do_recv(S, []);
И последний вызов do_recv
иногда работает, как ожидалось, и возвращает расположение сервера, но иногда он зависает и время ожидания, я полагаю, потому что сервер не закрывает сокет сам по себе.Итак, второй случай с таймаутом - это то, чего я хочу избежать, какие-либо идеи, как справиться с таким поведением?
UPD:
Я добавил gen_tcp:shutdown
вызовdo_recv
(см. Комментарий в примере кода), и это, похоже, решает проблему.Вопрос довольно дурацкий, я знаю, и решение похоже на предположение, может быть, кто-то еще может объяснить, что здесь происходит и как они обычно решают такую проблему.