在Erlang中,端口用于不同程序之间的通信。套接字是一种通信端点,它允许计算机使用Internet协议(IP)通过Internet进行通信。
有两种协议可用于通信。一个是UDP,另一个是TCP。UDP允许应用程序相互发送短消息(称为数据报),但不能保证这些消息的传递。它们也可能出现故障。另一方面,TCP提供了一个可靠的字节流,只要建立了连接,这些字节就按顺序传递。
让我们看一个使用UDP打开端口的简单示例。
-module(helloworld). -export([start/0]). start() -> {ok, Socket} = gen_udp:open(8789), io:fwrite("~p",[Socket]), io:fwrite("~p",[gen_udp:send (Socket,"localhost",8789,"Hello")]).
以上程序的输出如下。
#Port<0.376>ok
打开端口后,端口上还可以接收到一条消息。这是通过 recv 方法完成的。让我们看一下语法和下面的示例。
recv(Socket, length)
Socket −这是使用gen_udp:open命令创建的套接字。
Length −这是需要接收的消息的长度。
如果消息发送正确,则返回确定消息。
-module(helloworld). -export([start/0]). start() -> {ok, Socket} = gen_udp:open(8789), io:fwrite("~p",[Socket]), io:fwrite("~p",[gen_udp:send(Socket,"localhost",8789,"Hello")]), io:fwrite("~p",[gen_udp:recv(Socket, 20)]).
现在显然我们不能在同一程序中具有相同的发送和接收消息。您需要在不同的程序中定义它们。因此,让我们创建以下代码,该代码创建一个侦听消息的服务器组件和一个发送消息的客户端组件。
-module(helloworld). -export([start/0,client/1]). start() -> spawn(fun() -> server(4000) end). server(Port) -> {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]), io:format("server opened socket:~p~n",[Socket]), loop(Socket). loop(Socket) -> inet:setopts(Socket, [{active, once}]), receive {udp, Socket, Host, Port, Bin} -> io:format("server received:~p~n",[Bin]), gen_udp:send(Socket, Host, Port, Bin), loop(Socket) end. client(N) -> {ok, Socket} = gen_udp:open(0, [binary]), io:format("client opened socket=~p~n",[Socket]), ok = gen_udp:send(Socket, "localhost", 4000, N), Value = receive {udp, Socket, _, _, Bin} -> io:format("client received:~p~n",[Bin]) after 2000 -> 0 end, gen_udp:close(Socket), Value.
关于上述程序,需要注意以下几点。
我们定义了两个函数,第一个是服务器函数。这将用于监听端口4000。第二个是客户端,它将用于向服务器组件发送消息“ Hello”。
接收循环用于读取在定义循环内发送的消息。
现在你需要从两个窗口运行程序。第一个窗口将通过在 erl 命令行窗口中运行以下代码来运行服务器组件。
helloworld:start().
这将在命令行窗口中显示以下输出。
server opened socket:#Port<0.2314>
现在,在第二个erl命令行窗口中,运行以下命令。
Helloworld:client(“<<Hello>>”).
发出此命令时,以下输出将显示在第一个命令行窗口中。
server received:<<"Hello">>