2012-09-04 77 views
4

我的init()函數創建UDP套接字,並返回套接字值作爲一個國家。二郎:如何獲得來自gen_server的init()導致

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

%%% gen_server API 

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

如何在我的函數start()中獲取Socket?

回答

1

如果需要UDP套接字INT您啓動功能,您還可以在啓動功能創建它,並把它傳遞給開始鏈接調用作爲參數。這樣你就不必在創建它之後調用服務器。

rvirding指出,這將導致起動過程中從UDP套接字,而不是新生成的服務器接收郵件。請參閱評論以獲取更多信息。從問題中不清楚啓動方法需要什麼套接字,但要確保這是您想要的行爲。

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}. 
+4

是的,你可以這樣做。但打開一個插座的處理是由默認的控制過程,並且其接收在活動模式下的數據包的過程中,和如果死導致要關閉套接字。在這種情況下,這可能不是你想要的!解決方案是使用函數'gen_udp:controlling_process'將控制權轉移到gen_server。然而,這將打破'start' /'start_link'返回'{ok,Pid}'這是一件壞事的慣例。最好查詢服務器。 – rvirding

+0

你是對的,可能是真的,你不想讓起始過程成爲控制過程,儘管從上下文來看並不清楚。但是,爲什麼使用'gen_udp:controlling_process'會阻止你返回'{ok,Pid}'? – kjw0188

+0

當然,它不會阻止你返回'{ok,Pid}'。我的意思是,在原始問題中,他想從'start'函數返回'{ok,Socket}',**這將破壞約定。 – rvirding

6

你需要通過進行gen_server:call到新創建的gen_server進程來獲取插槽。例如:

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

而在gen_server添加類似:

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