concurrency - Erlang 中的并发

标签 concurrency erlang distributed

我是 erlang 新手,我正在尝试实现一个注册/登录服务器。我有一个注册新用户的功能,而且效果很好:

reg(Sock) ->
  receive
    {tcp, _, Usr} ->
      io:format("User: ~p ~n",[Usr])
  end,
  gen_tcp:send(Sock, [Usr]),
  receive
    {tcp, _, Pass} ->
      io:format(" a pass ~p~n",[Pass])
  end,
  gen_tcp:send(Sock, [Pass]),
  receive
    {tcp, _, Msg} ->
      case Msg of
        <<"condutor\n">> ->
        condutor ! {register, {Usr, Pass}};
        <<"passageiro\n">> ->
          io:format("passageiro~n")
      end
  end.

但现在我想要另一个函数来控制用户是否想要登录或注册,并发送正确的函数。但是当我添加此函数时,它不会读取用户的输入:

gestor(Sock) ->
  receive
    {tcp, _, Msg} ->
      case Msg of
        <<"login\n">> ->
          login(Sock);
        <<"registo\n">> ->
          gen_tcp:send(Sock, "OK"),
          reg(Sock) 
      end       
  end.

它接收用户的选项,将他发送到正确的函数,但随后它不会读取任何内容,我无法理解这一点,因为如果我直接调用函数 reg ,它就可以正常工作,但是如果我从另一个函数调用该函数,我将无法从套接字读取任何内容。

如果有人能帮助我,我将非常感激。

编辑: 非常感谢您的回复,我正在尝试实现一个Java客户端和一个Erlang服务器通过Tcp套接字进行通信,其目的是用户输入“registo”而不是用户名、密码和“condutor”或“passageiro” 。

套接字工作正常,因为如果我调用 reg(sock) 而不是 gestor(Sock) ,一切都会按预期工作,问题是当我在 gestor(Sock) 内调用 reg(Sock) 时,在这种情况下我无法收到用户在 reg 函数中输入。

-module(server2).
-export([server/1]).


server(Port) -> 
    {ok, LSock} = gen_tcp:listen(Port, [binary, {packet, line}, {reuseaddr, true}]),
    Condutor = spawn(fun()-> regUtente([]) end),
    register(condutor, Condutor),
    acceptor(LSock).

acceptor(LSock) -> 
   {ok, Sock} = gen_tcp:accept(LSock),
   spawn(fun() -> acceptor(LSock) end),
    io:format("Ligação estabelecida~n"),
   % reg(Sock). --- Caling reg directly, without passing through gestor WORKS FINE.
   gestor(Sock).

Java 客户端:

 import java.io.*;
 import java.net.*;

public class EchoClient {
    public static void main(String[] args) throws IOException {

    if (args.length != 2) {
        System.err.println(
            "Usage: java EchoClient <host name> <port number>");
        System.exit(1);
    }

    String hostName = args[0];
    int portNumber = Integer.parseInt(args[1]);

    try (
        Socket echoSocket = new Socket(hostName, portNumber);
        PrintWriter out =
            new PrintWriter(echoSocket.getOutputStream(), true);
        BufferedReader in =
            new BufferedReader(
                new InputStreamReader(echoSocket.getInputStream()));
        BufferedReader stdIn =
            new BufferedReader(
                new InputStreamReader(System.in))
    ) {
        String userInput;
        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);
            System.out.println("echo: " + in.readLine());
        }
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host " + hostName);
        System.exit(1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to " +
            hostName);
        System.exit(1);
    } 
   }
 }

最佳答案

发送“OK\n”作为对“registo”的响应。您的java代码正在使用readline,因此您需要一个行终止符。

关于concurrency - Erlang 中的并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37490858/

相关文章:

java - 并发文件移动访问

erlang - 为什么我在这个从 Erlang 翻译的 Elixir 程序中收到 FunctionClauseError ("no function clause matching")?

debugging - Erlang 是否有与 HLint 等价的工具?

go - 为什么这个 Go 程序没有像预期的那样进入死锁状态?

php - 尝试从 PHP 脚本访问时数据库被锁定

python - master/worker 是否可扩展?

list - 匹配和删除元组列表中的项目

replication - 在ArangoDB中,我们可以进行地理分布式分片吗

java - 在 Eclipse 中运行多个文件

sql - 涉及 SQL 时使用 Amazon EC2 自动缩放