短暂的端口混乱(加上一些erlang)

所以,我对短暂端口系统的理解是,有一个由四个值组成的元组来标识每个连接:{source ip,source port,dest ip,dest port},源端口是系统上的临时端口之一。 一个连接不能有任何其他的相同的元组,所以如果你正在从你的机器到另一个同一个端口进行一堆同时连接,你只能build立尽可能多的连接,因为你有免费的临时端口,因为这是只有可以改变的参数。 这一切对我来说都是有意义的(但是如果我错了,请纠正我)。

但是,理论上,如果您要使用两个不同的源IP地址,则可能会使连接数增加一倍。 我决定要testing这个,所以我写了一个erlang的客户端/服务器testing,它使得尽可能多的连接成为可能。 只使用一个IP地址,我的连接限制在52K左右。 我使用的IP地址是127.0.0.1。

然后我修改脚本也使用机器的本地networking地址(172.16.202.132)。 这绝对是两个ips:

# lsof -Pnl +M -i4 beam.smp 7528 1000 947u IPv4 3441692 0t0 TCP 172.16.202.132:32064->172.16.202.132:8888 (ESTABLISHED) beam.smp 7528 1000 948u IPv4 3441695 0t0 TCP 127.0.0.1:37225->127.0.0.1:8888 (ESTABLISHED) 

(重复似乎无止境地)

但是我的联系再一次达到了52k。 我修改了这两个程序,以便服务器和客户端将使用8889端口和8888.我几乎可以肯定,这会给我更多的,但我再次在52K封锁。 连接正常进行:

 # lsof -Pnl +M -i4 beam.smp 7528 1000 946u IPv4 3441689 0t0 TCP 172.16.202.132:26620->172.16.202.132:8889 (ESTABLISHED) beam.smp 7528 1000 947u IPv4 3441692 0t0 TCP 172.16.202.132:32064->172.16.202.132:8888 (ESTABLISHED) beam.smp 7528 1000 948u IPv4 3441695 0t0 TCP 127.0.0.1:37225->127.0.0.1:8888 (ESTABLISHED) beam.smp 7528 1000 949u IPv4 3441698 0t0 TCP 127.0.0.1:27965->127.0.0.1:8889 (ESTABLISHED) 

(重复似乎无止境地)

谁能澄清一下为什么会出现这种情况? 我使用的是Ubuntu 10.04,erlang R13B03。 以下是我用于客户端/服务器的代码:

服务器:

 -module(contest). -compile(export_all). -define(TCP_OPTS, [binary, {packet, raw}, {nodelay, true}, {reuseaddr, true}, {active, false},{keepalive,true}]). start() -> erlang:register(counter,spawn(fun()->?MODULE:counter(0) end)), %Gets the listen socket, generates acceptor threads case gen_tcp:listen(8888, ?TCP_OPTS) of {ok, Listen1} -> ?MODULE:gen_accepts(10,Listen1) end, case gen_tcp:listen(8889, ?TCP_OPTS) of {ok, Listen2} -> ?MODULE:gen_accepts(10,Listen2) end, ?MODULE:supervisor_loop({Listen1,Listen2}). %Serves the purpose of keeping the listen socket open %indefinitely supervisor_loop(LS) -> receive _ -> ?MODULE:supervisor_loop(LS) end. %Generates I acceptor threads which constantly listen for %new connections. Upon getting one, a new acceptor thread %is spawned and the one which receieved a connection %continues on to process the connection gen_accepts(0,_) -> ok; gen_accepts(I,LS) -> spawn(?MODULE,accept_loop,[LS]), ?MODULE:gen_accepts(I-1,LS). %Acceptor loop which spawns off sock processors when connections %come in accept_loop(Listen) -> case gen_tcp:accept(Listen) of {ok, Socket} -> Pid = spawn(fun()->?MODULE:process_sock(Socket) end), gen_tcp:controlling_process(Socket,Pid), whereis(counter)!plus; {error,_} -> ok end, ?MODULE:accept_loop(Listen). %Holds socket, doesn't do anything process_sock(Sock) -> receive _ -> process_sock(Sock) end. counter(C) -> receive plus -> io:fwrite("~p\n",[C+1]), counter(C+1) end. 

客户:

 -module(flooder). -compile(export_all). start() -> spawn(fun()->start("172.16.202.132",8888)end), spawn(fun()->start("172.16.202.132",8889)end). start(Ip,Port) -> spawn(?MODULE,connect,[Ip,Port]), timer:sleep(2), case Ip of "127.0.0.1" -> ?MODULE:start("172.16.202.132",Port); "172.16.202.132" -> ?MODULE:start("127.0.0.1",Port) end. connect(Ip,Port) -> case gen_tcp:connect( Ip, Port, [list,{active,true}] ) of {ok, Sock} -> io:fwrite("Connected on ~s\n",[Ip]),loop(Sock); {error,E} -> eMessage("connect",E) end. loop(Sock) -> receive _ -> loop(Sock) end. eMessage(W,E) -> io:fwrite("~w at ~s: ~s\n",[self(),W,E]). 

无论您正在监听多less个IP地址,您的操作系统都具有最大数量的IPv4连接。 这可能是你遇到的限制。 每个进程和每个用户也可能有限制。 检查所有这些。