Inconsistent tcp_socket behavior in Erlang

穿精又带淫゛_ 提交于 2019-12-13 06:18:13

问题


In order to read input 1 character at a time, I wrote a c program that uses ssty raw.

I use this character.c program to call an erlang file, naive_tcp.erl which sends a message over socket to a listening server on the same machine.

I expect this server, naive_tcp2.erl, to write back with 26 lines of descending integers and an 80 character long string with 2 "|" pipes in it, so that it lines up on the 80x26 terminal.

What happens instead is very inconsistent printing of data. Running ./character.c, then pressing a key on the keyboard every few seconds, you can see the output starting with "26" and descending down to "1", but instead you can see it descend to "23", "21" or only "24".

character.c:

#include<stdio.h>
#include<stdlib.h>

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, <<"quit", _/binary>>} ->
      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, <<"quit", _/binary>>} ->
      gen_tcp:close(Socket);
    {tcp, Socket, Bin} ->
      % gen_tcp:send(Socket, Bin)
      % Msg = binary:bin_to_list(Bin),
      format(Socket)
  end,
  handle(Socket).

running ./character and hitting keys:

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

来源:https://stackoverflow.com/questions/42755951/inconsistent-tcp-socket-behavior-in-erlang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!