简体   繁体   中英

Concurrence in Erlang

I'm new in erlang and I'm trying to implement a register/login server. I have a function to register new users, and it works well:

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.

But now I want to have another function that controlls if a user wants to login or register, and send the proper function. But when I add this function it doesn't read the input of the user:

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

It receives the option of the user, sends him to the right function but then it doesn't read anything, I can't understand this because if I call the function reg directly it works fine, but if I call that function from another function, I can't read nothing from the socket.

If anyone could help me I would apreciate it very much.

EDITED: Thanks a lot for your replies, I'm trying to implement a Java client and a Erlang server communicating through a Tcp socket, it's intended that the user types "registo" than a username, a password, and "condutor" or "passageiro".

The socket works fine because if I call reg(sock) instead of gestor(Sock) everything works as expected, the problem is when I call reg(Sock) inside gestor(Sock) in this case I can't receive the user input in reg function.

-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 Client:

 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);
    } 
   }
 }

Send "OK\\n" as a response to "registo." Your java code is using readline so you need a line terminator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM