Erlang:如何从gen_服务器中的init()获取结果

Erlang:如何从gen_服务器中的init()获取结果,erlang,gen-server,Erlang,Gen Server,函数的作用是:创建UDP套接字并将套接字值作为状态返回 start() -> {ok, ServerPid} = gen_server:start_link(?MODULE, [], []). %%% gen_server API init([]) -> {ok, Socket} = gen_udp:open(8888, [list, {active,false}]), {ok, Socket}. 如何在函数start()中获取套

函数的作用是:创建UDP套接字并将套接字值作为状态返回

start() ->
        {ok, ServerPid} = gen_server:start_link(?MODULE, [], []).

%%% gen_server API

init([]) ->
        {ok, Socket} = gen_udp:open(8888, [list, {active,false}]),
        {ok, Socket}.

如何在函数start()中获取套接字?

您需要通过对新创建的gen\u服务器进程进行
gen\u服务器:调用
来获取套接字。e、 g:

start() ->
        {ok, ServerPid} = gen_server:start_link(?MODULE, [], []),
        Socket = gen_server:call(ServerPid, fetch_socket),
        ... Use Socket ...
在gen_服务器中添加如下内容:

handle_call(fetch_socket, _From, State) ->
   {reply, State, State}. %% State == Socket

如果在start函数中需要udp套接字,还可以在start函数中创建它,并将其作为参数传递给start link调用。这样,您就不必在创建服务器后调用它

rvirding指出,这将导致启动进程从udp套接字接收消息,而不是从新生成的服务器接收消息。有关更多信息,请参阅注释。这个问题并不清楚start方法中到底需要套接字做什么,但请确保这是您想要的行为

start() ->
    {ok, Socket} = gen_udp:open(8888, [list, {active,false}]),
    {ok, ServerPid} = gen_server:start_link(?MODULE, Socket, []).

%%% gen_server API

init(Socket) ->
    {ok, Socket}.

是的,你可以这样做。但是打开套接字的进程默认为控制进程,并且是在活动模式下接收数据包的进程,如果它死亡,则导致套接字关闭。在这种情况下,这可能不是你想要的!解决方案是使用功能
gen\u udp:controlling\u process
将控制权转移到gen\u服务器。但是,这将打破
start
/
start\u链接
返回
{ok,Pid}
的惯例,这是一件坏事。最好是查询服务器。您是对的,您可能不想让启动进程成为控制进程,尽管从上下文看不清楚。但是,为什么使用
gen\u udp:controlling\u process
会阻止您返回
{ok,Pid}
?当然它不会阻止您返回
{ok,Pid}
。我的意思是,在最初的问题中,他想从
start
函数返回
{ok,Socket}
,这将打破惯例。