Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 在Erlang中通过RPC在远程节点上创建套接字时,无法接受套接字上的连接_Sockets_Erlang_Gen Tcp - Fatal编程技术网

Sockets 在Erlang中通过RPC在远程节点上创建套接字时,无法接受套接字上的连接

Sockets 在Erlang中通过RPC在远程节点上创建套接字时,无法接受套接字上的连接,sockets,erlang,gen-tcp,Sockets,Erlang,Gen Tcp,我正在努力找出gen_tcp的原因:accept总是返回一个{error,closed}响应 基本上,我有一个主管,负责创建监听套接字: gen_tcp:listen(8081, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]), 然后将该套接字传递给子代,这是gen_服务器行为的实现。然后,子节点接受套接字上的连接 accept(ListeningSocket, {ok, Socket}) ->

我正在努力找出gen_tcp的原因:accept总是返回一个{error,closed}响应

基本上,我有一个主管,负责创建监听套接字:

gen_tcp:listen(8081, [binary, {packet, 0}, {active, false}, {reuseaddr, true}]),
然后将该套接字传递给子代,这是gen_服务器行为的实现。然后,子节点接受套接字上的连接

accept(ListeningSocket, {ok, Socket}) ->                                   
    spawn(fun() -> loop(Socket) end),                                      
    accept(ListeningSocket);
accept(_ListeningSocket, {error, Error}) ->
    io:format("Unable to listen on socket: ~p.~n", [Error]),
    gen_server:call(self(), stop).

accept(ListeningSocket) ->                                                 
    accept(ListeningSocket, gen_tcp:accept(ListeningSocket)).                                                                                             

loop(Socket) ->                                                            
    case gen_tcp:recv(Socket, 0) of                                        
        {ok, Data} ->                                                      
            io:format("~p~n", [Data]),                                     
            process_request(Data),                                         
            gen_tcp:send(Socket, Data),                                    
            loop(Socket);                                                  
        {error, closed} -> ok                                              
   end.
我在本地加载supervisor和gen_server BEAM二进制文件,并通过对code:load_binary的RPC调用将它们加载到另一个节点(在同一台机器上运行)上。 接下来,我通过一个RPC调用执行监控程序,然后启动服务器。{error,closed}在这个场景中总是由gen_tcp:accept返回

如果我在登录到节点外壳程序时运行管理器和服务器,那么服务器可以接受连接而不会出现问题。这包括到远程节点的“remsh”,如果我之前将其升级为启动服务器失败,该远程节点将无法接受连接

我似乎能够通过单独使用shell来复制这个问题:

[Terminal 1]: erl -sname node -setcookie abc -distributed -noshell

[Terminal 2]: erl -sname rpc -setcookie abc:

              net_adm:ping('node@verne').
              {ok, ListeningSocket} = rpc:call('node@verne', gen_tcp, listen, [8081, [binary, {packet, 0}, {active, true}, {reuseaddr, true}]]).
              rpc:call('node@verne', gen_tcp, accept, [ListeningSocket]).
对最终RPC的响应是{error,closed}

这可能与套接字/端口所有权有关吗


如果有帮助,没有客户端等待连接,我也不会在任何地方设置超时。

每个
rpc:call
在目标节点上启动一个新进程来处理请求。在最后一个示例中,您的第一个调用在这样一个进程内创建了一个侦听套接字,当该进程在rpc调用结束时终止时,该套接字关闭。因此,尝试接受的第二个rpc调用由于已关闭的侦听套接字而失败


你的设计在几个方面似乎与众不同。例如,让主管打开插座是不正常的。您还说孩子是一个
genu服务器
,但您显示了一个手动
recv
循环,如果在
genu服务器
中运行,它将阻止它。相反,你可以解释一下你想要完成什么,并请求他人帮助你设计出符合你目标的设计。

史蒂夫,这是有道理的。感谢您的解释。这个问题是在不久前我在Erlang中试验套接字时出现的。我只是没有抽出时间早些问这个问题。如果我没记错的话,我的初衷是让多个gen_服务器在同一个套接字上接受连接。在目标节点上生成一个新进程来处理请求,这一事实解释了为什么通过RPC启动gen_服务器时套接字会立即关闭。