Erlang中的tcp_socket行为不一致
为了一次读取输入1个字符,我写了一个使用ssty raw
ac程序。
我使用这个character.c
程序来调用一个erlang文件, naive_tcp.erl
通过socket将消息发送到同一台机器上的监听服务器。
我希望这个服务器naive_tcp2.erl
用26行降序整数和80字符长字符串写回2“|” 管道在其中,以便它在80×26终端上排队。
相反,会发生非常不一致的数据打印。 运行./character.c
,然后每隔几秒按键盘上的一个键,你可以看到输出以"26"
开头并下降到"1"
,但你可以看到它下降到"23"
, "21"
或仅"24"
。
character.c:
#include #include int main(void){ system ("clear"); int c; /* use system call to make terminal send all keystrokes directly to stdin */ system ("/bin/stty raw"); while((c=getchar())!= '.') { char command[100]; sprintf(command, "erl -noshell -run naive_tcp go -s erlang halt"); system(command); printf("\r\n"); /* type a period to break out of the loop, since CTRL-D won't work raw */ } /* use system call to set terminal behaviour to more normal behaviour */ system ("/bin/stty cooked"); system ("clear"); system ("echo ok\n"); return 0; }
naive_tcp.erl:
-module(naive_tcp). -compile(export_all). go() -> Text = "hello", {ok, Socket} = gen_tcp:connect({127,0,0,1}, 8094, []), send(Socket, Text). format() -> format(26). format(0) -> io:format("\r\n"); format(N) -> io:format(integer_to_list(N)), io:format(" | | "), format(N - 1). send(Socket, Msg) -> inet:setopts(Socket, [{active, once}]), gen_tcp:send(Socket, Msg), receive {tcp, Socket, <>} -> gen_tcp:close(Socket); {tcp, _, Res} -> gen_tcp:close(Socket), io:format(Res ++ "\r\n") end.
naive_tcp2.erl
-module(naive_tcp2). -compile(export_all). go() -> go(8094). go(Port) -> Pid = spawn_link(fun() -> {ok, Listen} = gen_tcp:listen(Port, [binary, {active, false}]), spawn(fun() -> acceptor(Listen) end), timer:sleep(infinity) end), {ok, Pid}. acceptor(ListenSocket) -> {ok, Socket} = gen_tcp:accept(ListenSocket), spawn(fun() -> acceptor(ListenSocket) end), handle(Socket). format(Socket) -> format(26, Socket). format(0, Socket) -> gen_tcp:send(Socket, "\r\n"); format(N, Socket) -> gen_tcp:send(Socket, integer_to_list(N)), gen_tcp:send(Socket, " | | "), format(N - 1, Socket). handle(Socket) -> inet:setopts(Socket, [{active, once}]), receive {tcp, Socket, <>} -> gen_tcp:close(Socket); {tcp, Socket, Bin} -> % gen_tcp:send(Socket, Bin) % Msg = binary:bin_to_list(Bin), format(Socket) end, handle(Socket).
运行./character
并按键:
26 | | 25 | | 24 | | 23 | | 26 | | 25 | | 24 | | 23 | | 22 | | 21 26 | | 25 | | 24 | | 23 | | 26 | | 25 | | 24 | | 23 | | 22 | | 21 | | 20 | | 26 | | 25 | | 24 | | 23 | | 22 | | 21 | | 20 26 | | 25 | | 24