我最近在Mac OS X中遇到的ECONNRESET
heisenbug般的出現與二郎(不是我的機器!)。爲了簡化問題的根源,爲了更好地理解錯誤,我編寫了以下模塊來觸發ECONNRESET
。不幸的是,我自己並不擁有Mac。在我的Linux(ArchLinux的)下面的代碼不會隨着{error,econnreset}
一個badmatch崩潰,但{error,closed}
代替。Erlang:如何在Linux上觸發ECONNRESET?
-module(econnreset).
-export([run/0]).
run() ->
Pid = spawn_link(fun listen_and_accept/0),
Pid ! {get_port,self()},
Port = receive {port,P} -> P end,
{ok,Socket} = gen_tcp:connect("localhost", Port, [{active,false}]),
ok = gen_tcp:send(Socket, lists:duplicate(100, $a)),
%% On the following line, I expected a badmatch w/ {error,econnreset}
{ok,_} = gen_tcp:recv(Socket, 0, 1000),
ok = gen_tcp:close(Socket),
ok.
listen_and_accept() ->
{ok,LSocket} = gen_tcp:listen(0, [binary,{active,false}]),
{ok,Port} = inet:port(LSocket),
receive {get_port,Pid} -> Pid ! {port,Port} end,
{ok,Socket} = gen_tcp:accept(LSocket),
{ok,Bin} = gen_tcp:recv(Socket, 1), %=> read only 1 byte to trigger tcp RST
io:format("Server read ~p~n", [Bin]),
gen_tcp:close(Socket),
gen_tcp:close(LSocket).
正如我只能在Mac OS X中遇到ECONNRESET
但並沒有在Linux上,這可以歸結爲兩個問題:
- 是上面甚至能生產
ECONNRESET
的代碼通過調用recv/2
? - Mac OS X和Linux的行爲在這裏有所不同嗎?