ssh_tcp_wrap.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 122 行
ERL
122 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%%%% Description: tcp listen and accept-loop-module(ssh_tcp_wrap).-export([spawn_server/3, server/4]).-export([server_init/4, server_loop/3, accept_loop/4]). %% helper-define(ACCEPT_TIMEOUT, 10000).%% Spawn the server loopspawn_server(Port, Opts, Fun) -> Pid = spawn(?MODULE, server_init, [self(),Port,Opts,Fun]), Ref = erlang:monitor(process, Pid), receive {'DOWN', Ref, _, _, Reason} -> {error, Reason}; {Pid, Reply} -> erlang:demonitor(Ref), Reply end.server_init(Starter, Port, Opts, Fun) -> case gen_tcp:listen(Port, Opts) of {ok, Listen} -> if Port == 0 -> case inet:sockname(Listen) of {ok, {_,Port1}} -> Starter ! {self(), {ok,self(),Port1}}, server_loop(self(), Listen, Fun); Error -> gen_tcp:close(Listen), Starter ! {self(), Error} end; true -> Starter ! {self(), {ok,self(),Port}}, server_loop(self(), Listen, Fun) end; Error -> error_logger:format( "Failed to listen on port: ~p opts:~p: rsn:~p~n", [Port, Opts,Error]), Starter ! {self(), Error} end.%% Run the server loopserver(Port, Opts, Fun, From) -> case gen_tcp:listen(Port, Opts) of {ok, Listen} -> From ! ok, server_loop(self(), Listen, Fun); Error -> error_logger:format( "Failed to listen on port: ~p opts:~p: rsn:~p~n", [Port, Opts,Error]), Error end.server_loop(User, Listen, Fun) -> Pid = spawn(fun() -> ?MODULE:accept_loop(User, erlang:monitor(process,User), Listen, Fun) end), Ref = erlang:monitor(process, Pid), receive {'DOWN', Ref, _, _, _Reason} -> ?MODULE:server_loop(User, Listen, Fun); {Pid, stop} -> stopped; {User, stop} -> stopped; {Pid, _Result} -> erlang:demonitor(Ref), ?MODULE:server_loop(User, Listen, Fun) end.accept_loop(User, Ref, Listen, Fun) -> %% Timeout makes it possible to replace this module %% once every ?ACCEPT_TIMEOUT milliseconds case gen_tcp:accept(Listen, ?ACCEPT_TIMEOUT) of {ok, S} -> %% poll if 'User' is still alive receive {'DOWN', Ref, _, _, Reason} -> gen_tcp:close(S), exit(Reason) after 0 -> User ! {self(), ok}, Fun(S) end; {error, timeout} -> %% poll if 'User' is still alive receive {'DOWN', Ref, _, _, Reason} -> exit(Reason) after 0 -> ?MODULE:accept_loop(User, Ref, Listen, Fun) end; {error, closed} -> Listen ! {self(), stop}; Error -> Listen ! {self(), Error} end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?