Erlang 中的并发
Concurrence in Erlang
我是 erlang 的新手,我正在尝试实现 register/login 服务器。我有注册新用户的功能,效果很好:
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 客户端和一个通过 Tcp 套接字通信的 Erlang 服务器,它的目的是用户键入 "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
,因此您需要一个行终止符。
我是 erlang 的新手,我正在尝试实现 register/login 服务器。我有注册新用户的功能,效果很好:
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 客户端和一个通过 Tcp 套接字通信的 Erlang 服务器,它的目的是用户键入 "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
,因此您需要一个行终止符。