4

My init() function creates UDP Socket and Returns Socket value as a State.

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

%%% gen_server API

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

How can I get Socket in my function start()?

johlo
  • 5,422
  • 1
  • 18
  • 32
Atlas
  • 179
  • 1
  • 2
  • 9

2 Answers2

6

You need to fetch the socket by making a gen_server:call to the newly created gen_server process. e.g.:

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

And in the gen_server add something like:

handle_call(fetch_socket, _From, State) ->
   {reply, State, State}. %% State == Socket
johlo
  • 5,422
  • 1
  • 18
  • 32
1

If you need the udp socket int your start function, you can also create it in the start function, and pass it to the start link call as a parameter. That way you don't have to call the server after you created it.

rvirding points out that this will cause the starting process to receive messages from the udp socket, not the newly spawned server. See the comments for more information. It's not clear from the question what exactly the socket is needed for in the start method, but make sure this is the behavior you want.

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}.
kjw0188
  • 3,625
  • 16
  • 28
  • 4
    Yes, you can do it this way. BUT the process which opens a socket is by default the controlling process and is the process which receives the packets in active mode, and if it dies causes the socket to be closed. Which is probably not what you want in this case! The solution is to transfer control to the gen_server using the function `gen_udp:controlling_process`. However, this will break the convention that a `start`/`start_link` returns `{ok,Pid}` which is a Bad Thing. It is better to query the server. – rvirding Sep 05 '12 at 07:46
  • You're right, it's probably true you don't want to have the starting process be the controlling process, although it isn't clear from context. However, why would using `gen_udp:controlling_process` prevent you from returning `{ok, Pid}`? – kjw0188 Sep 05 '12 at 21:11
  • Of course it wouldn't prevent you from returning `{ok,Pid}`. What I meant was that in the original question he wanted to return `{ok,Socket}` from the `start` function and **THIS** would break the convention. – rvirding Sep 06 '12 at 08:34