Erlang客户端服务器错误
我正在读《编程Erlang》,第253页有一个运行客户机/服务器连接的示例。下面的代码建议在两个单独的erlang控制台窗口中运行以下命令,我从中得到以下错误Erlang客户端服务器错误,erlang,client-server,Erlang,Client Server,我正在读《编程Erlang》,第253页有一个运行客户机/服务器连接的示例。下面的代码建议在两个单独的erlang控制台窗口中运行以下命令,我从中得到以下错误 2> socket_examples:nano_client_eval("list_to_tuple([2+3*4,10+20])"). ** exception error: no match of right hand side value {error,econnrefused} in function socke
2> socket_examples:nano_client_eval("list_to_tuple([2+3*4,10+20])").
** exception error: no match of right hand side value {error,econnrefused}
in function socket_examples:nano_client_eval/1 (socket_examples.erl, line 28)
用于服务器端的命令:
socket\u示例:启动nano\u服务器()。
用于客户端的命令:
socket\u示例:nano\u client\u eval(“列表到元组([2+3*4,10+20])。
我没有打开防火墙,但这不应该是一个问题,因为它不在线
%% ---
%% Excerpted from "Programming Erlang",
%%---
-module(socket_examples).
-compile(export_all).
-import(lists, [reverse/1]).
nano_get_url() ->
nano_get_url("www.google.com").
nano_get_url(Host) ->
{ok,Socket} = gen_tcp:connect(Host,80,[binary, {packet, 0}]), %% (1)
ok = gen_tcp:send(Socket, "GET / HTTP/1.0\r\n\r\n"), %% (2)
receive_data(Socket, []).
receive_data(Socket, SoFar) ->
receive
{tcp,Socket,Bin} -> %% (3)
receive_data(Socket, [Bin|SoFar]);
{tcp_closed,Socket} -> %% (4)
list_to_binary(reverse(SoFar)) %% (5)
end.
nano_client_eval(Str) ->
{ok, Socket} =
gen_tcp:connect("localhost", 2345,
[binary, {packet, 4}]),
ok = gen_tcp:send(Socket, term_to_binary(Str)),
receive
{tcp,Socket,Bin} ->
io:format("Client received binary = ~p~n",[Bin]),
Val = binary_to_term(Bin),
io:format("Client result = ~p~n",[Val]),
gen_tcp:close(Socket)
end.
start_nano_server() ->
{ok, Listen} = gen_tcp:listen(2345, [binary, {packet, 4}, %% (6)
{reuseaddr, true},
{active, true}]),
{ok, Socket} = gen_tcp:accept(Listen), %% (7)
gen_tcp:close(Listen), %% (8)
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Bin} ->
io:format("Server received binary = ~p~n",[Bin]),
Str = binary_to_term(Bin), %% (9)
io:format("Server (unpacked) ~p~n",[Str]),
Reply = lib_misc:string2value(Str), %% (10)
io:format("Server replying = ~p~n",[Reply]),
gen_tcp:send(Socket, term_to_binary(Reply)), %% (11)
loop(Socket);
{tcp_closed, Socket} ->
io:format("Server socket closed~n")
end.
error_test() ->
spawn(fun() -> error_test_server() end),
lib_misc:sleep(2000),
{ok,Socket} = gen_tcp:connect("localhost",4321,[binary, {packet, 2}]),
io:format("connected to:~p~n",[Socket]),
gen_tcp:send(Socket, <<"123">>),
receive
Any ->
io:format("Any=~p~n",[Any])
end.
error_test_server() ->
{ok, Listen} = gen_tcp:listen(4321, [binary,{packet,2}]),
{ok, Socket} = gen_tcp:accept(Listen),
error_test_server_loop(Socket).
error_test_server_loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("received:~p~n",[Data]),
atom_to_list(Data),
error_test_server_loop(Socket)
end.
%%---
%%摘自“编程Erlang”,
%%---
-模块(插座示例)。
-编译(全部导出)。
-导入(列表,[反向/1])。
nano_get_url()->
nano_get_url(“www.google.com”)。
nano\u get\u url(主机)->
{ok,Socket}=gen_tcp:connect(主机,80,[二进制,{packet,0}]),%%(1)
ok=gen\u tcp:send(套接字,“GET/HTTP/1.0\r\n\r\n”),%%(2)
接收_数据(套接字,[])。
接收数据(插座、SoFar)->
接收
{tcp,套接字,Bin}->%%(3)
接收|u数据(套接字,[Bin|SoFar]);
{tcp_已关闭,套接字}->%%(4)
列表到二进制(反向(SoFar))%%(5)
结束。
纳米客户评估(Str)->
{好的,套接字}=
gen_tcp:connect(“本地主机”,2345,
[二进制,{packet,4}]),
ok=gen_tcp:send(套接字,术语到二进制(Str)),
接收
{tcp,套接字,Bin}->
io:format(“客户端接收的二进制文件=~p~n,[Bin]),
Val=二进制项到二进制项(Bin),
io:格式(“客户端结果=~p~n,[Val]),
gen_tcp:关闭(套接字)
结束。
启动\u nano\u服务器()->
{ok,Listen}=gen_tcp:Listen(2345,[二进制,{packet,4},%%)(6)
{reuseaddr,true},
{active,true}]),
{ok,Socket}=gen_tcp:accept(Listen),%%(7)
gen_tcp:关闭(侦听),%%(8)
回路(插座)。
循环(套接字)->
接收
{tcp,套接字,Bin}->
io:format(“服务器接收的二进制文件=~p~n,[Bin]),
Str=二进制项(Bin),%%(9)
io:format(“服务器(未打包)~p~n,[Str]),
Reply=lib_misc:string2value(Str),%%(10)
io:format(“服务器应答=~p~n”,[Reply]),
gen_tcp:send(套接字,术语_to_二进制(应答)),%%(11)
回路(插座);
{tcp_已关闭,套接字}->
io:格式(“服务器套接字已关闭~n”)
结束。
错误_test()->
繁殖(fun()->错误\u测试\u服务器()结束),
lib_misc:睡眠(2000年),
{ok,Socket}=gen_tcp:connect(“localhost”,4321,[二进制,{packet,2}]),
io:格式(“连接到:~p~n,[Socket]),
gen_tcp:发送(套接字,),
接收
任何->
io:format(“Any=~p~n”,[Any])
结束。
错误\u测试\u服务器()->
{ok,Listen}=gen_tcp:Listen(4321,{binary,{packet,2}]),
{ok,Socket}=gen_tcp:accept(Listen),
错误\u测试\u服务器\u循环(套接字)。
错误\u测试\u服务器\u循环(套接字)->
接收
{tcp,套接字,数据}->
io:格式(“接收:~p~n,[Data]),
原子到原子列表(数据),
错误\u测试\u服务器\u循环(套接字)
结束。
您收到的消息({error,econnreference})显示服务器已关闭
正如Muzaaya所说,{packet,N}在系统中应该是一致的。如果不是这样,服务器将在二进制\u到\u术语转换中失败并崩溃(我没有深入研究这个问题,但我想这与信息的传输方式有关)
接下来的请求将收到连接被拒绝消息
通过Muzaaya建议的更改,服务器能够执行二进制\u到\u项,并且在调用b_misc:string2value之前一切都正常。。。这是不包括在后
我注意到一些奇怪的事情,然后:
- 我使用spawn(socket\u示例,start\u nano\u server,[])启动了服务器
- 调用未定义的模块-->正常行为时服务器崩溃
- 但是shell挂起,我无法输入任何新命令
-module(socket_examples).
-compile(export_all).
-import(lists, [reverse/1]).
nano_get_url() ->
nano_get_url("www.google.com").
nano_get_url(Host) ->
{ok,Socket} = gen_tcp:connect(Host,80,[binary, {packet, 0}]), %% (1)
ok = gen_tcp:send(Socket, "GET / HTTP/1.0\r\n\r\n"), %% (2)
receive_data(Socket, []).
receive_data(Socket, SoFar) ->
receive
{tcp,Socket,Bin} -> %% (3)
receive_data(Socket, [Bin|SoFar]);
{tcp_closed,Socket} -> %% (4)
list_to_binary(reverse(SoFar)) %% (5)
end.
nano_client_eval(Str) ->
{ok, Socket} =
gen_tcp:connect("localhost", 2345,
[binary, {packet, 0}]),
ok = gen_tcp:send(Socket, term_to_binary(Str)),
R = receive
{tcp,Socket,Bin} ->
io:format("Client received binary = ~p~n",[Bin]),
Val = binary_to_term(Bin),
io:format("Client result = ~p~n",[Val]),
{ok,Val}
after 5000 ->
io:format("nano_client_eval got not answer to ~p~n",[Str]),
{error,timeout}
end,
% gen_tcp:close(Socket),
R.
start_nano_server() ->
{ok, Listen} = gen_tcp:listen(2345, [binary, {packet, 0}, %% (6)
{reuseaddr, true},
{active, true}]),
% {ok, Socket} = gen_tcp:accept(Listen), %% (7)
% gen_tcp:close(Listen), %% (8)
% loop(Socket).
loop(Listen).
% loop(Socket) ->
loop(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
receive
{tcp, Socket, Bin} ->
io:format("Server received binary = ~p~n",[Bin]),
Str = binary_to_term(Bin), %% (9)
io:format("Server (unpacked) ~p~n",[Str]),
% Reply = lib_misc:string2value(Str), %% (10)
Reply = string:to_upper(Str), %% (10)
io:format("Server replying = ~p~n",[Reply]),
gen_tcp:send(Socket, term_to_binary(Reply)), %% (11)
% loop(Socket);
loop(Listen);
{tcp_closed, Socket} ->
io:format("Server socket closed~n")
end.
error_test() ->
spawn(fun() -> error_test_server() end),
lib_misc:sleep(2000),
{ok,Socket} = gen_tcp:connect("localhost",4321,[binary, {packet, 0}]),
io:format("connected to:~p~n",[Socket]),
gen_tcp:send(Socket, <<"123">>),
receive
Any ->
io:format("Any=~p~n",[Any])
end.
error_test_server() ->
{ok, Listen} = gen_tcp:listen(4321, [binary,{packet,0}]),
{ok, Socket} = gen_tcp:accept(Listen),
error_test_server_loop(Socket).
error_test_server_loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("received:~p~n",[Data]),
atom_to_list(Data),
error_test_server_loop(Socket)
end.
-模块(插座示例)。
-编译(全部导出)。
-导入(列表,[反向/1])。
nano_get_url()->
nano_get_url(“www.google.com”)。
nano\u get\u url(主机)->
{ok,Socket}=gen_tcp:connect(主机,80,[二进制,{packet,0}]),%%(1)
ok=gen\u tcp:send(套接字,“GET/HTTP/1.0\r\n\r\n”),%%(2)
接收_数据(套接字,[])。
接收数据(插座、SoFar)->
接收
{tcp,套接字,Bin}->%%(3)
接收|u数据(套接字,[Bin|SoFar]);
{tcp_已关闭,套接字}->%%(4)
列表到二进制(反向(SoFar))%%(5)
结束。
纳米客户评估(Str)->
{好的,套接字}=
gen_tcp:connect(“本地主机”,2345,
[二进制,{packet,0}]),
ok=gen_tcp:send(套接字,术语到二进制(Str)),
R=接收
{tcp,套接字,Bin}->
io:format(“客户端接收的二进制文件=~p~n,[Bin]),
Val=二进制项到二进制项(Bin),
io:格式(“客户端结果=~p~n,[Val]),
{好的,Val}
5000后->
io:format(“nano_client_eval没有得到~p~n的答案,[Str]),
{错误,超时}
完,,
%gen_tcp:关闭(插座),
R
启动\u nano\u服务器()->
{ok,Listen}=gen_tcp:Listen(2345,[二进制,{packet,0},%%)(6)
{reuseaddr,true},
{active,true}]),
%{ok,Socket}=gen_tcp:accept(Listen),%%(7)
%gen_tcp:关闭(侦听),%%(8)
%回路(插座)。
循环(听)。
%循环(套接字)->
循环(听)->
{ok,Socket}=gen_tcp:accept(Listen),
接收
{tcp,套接字,Bin}->
io:format(“服务器接收到的二进制文件