当前位置: 首页 > 文档资料 > Erlang 中文教程 >

Ports

优质
小牛编辑
131浏览
2023-12-01

在Erlang中,端口用于不同程序之间的通信。 套接字是一种通信端点,允许计算机使用Internet协议(IP)通过Internet进行通信。

端口使用的协议类型

有两种类型的协议可用于通信。 一个是UDP,另一个是TCP。 UDP允许应用程序相互发送短消息(称为数据报),但不保证这些消息的传递。 它们也可能无序到达。 另一方面,TCP提供可靠的字节流,只要建立连接就按顺序传送。

让我们看一个使用UDP打开端口的简单示例。

例子 (Example)

-module(helloworld). 
-export([start/0]). 
start() -> 
   {ok, Socket} = gen_udp:open(8789), 
   io:fwrite("~p",[Socket]).

关于上述程序需要注意以下事项

  • gen_udp包含用于UDP通信的Erlang中的模块。

  • 这里8789是在Erlang打开的端口号。 您需要确保此端口号可用且可以使用。

上述计划的输出是 -

#Port<0.376>

在端口上发送消息

打开端口后,可以在端口上发送消息。 这是通过send方法完成的。 我们来看一下语法和下面的例子。

语法 (Syntax)

send(Socket, Address, Port, Packet)

参数 (Parameters)

  • Socket - 这是使用gen_udp:open命令创建的套接字。

  • Address - 这是必须将消息发送到的机器地址。

  • port - 这是需要发送消息的端口号。

  • Packet - 这是需要发送的数据包或消息详细信息。

返回值 (Return Values)

如果消息已正确发送,则会返回ok消息。

例如 (For example)

-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")]).

输出 (Output)

上述程序的输出如下。

#Port<0.376>ok

在端口上接收消息

打开端口后,也可以在端口上接收消息。 这是通过recv method完成的。 我们来看一下语法和下面的例子。

语法 (Syntax)

recv(Socket, length)

参数 (Parameters)

  • Socket - 这是使用gen_udp:open命令创建的套接字。

  • Length - 这是需要接收的消息的长度。

返回值 (Return Values)

如果消息已正确发送,则会返回ok消息。

例如 (For example)

-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)]).

完整计划

现在显然我们不能在同一个程序中拥有相同的发送和接收消息。 您需要在不同的程序中定义它们。 因此,让我们创建以下代码,该代码创建一个侦听消息的服务器组件和一个发送消息的客户端组件。

例子 (Example)

-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.

关于上述程序需要注意以下事项。

  • 我们定义了2个函数,第一个是服务器。 这将用于侦听端口4000.第二个是用于将消息“Hello”发送到服务器组件的客户端。

  • 接收循环用于读取定义循环内发送的消息。

输出 (Output)

现在您需要从2个窗口运行该程序。 第一个窗口将用于通过在erl command line window运行以下代码来运行服务器组件。

helloworld:start().

这将在命令行窗口中显示以下输出。

server opened socket:#Port<0.2314>

现在,在第二个erl命令行窗口中,运行以下命令。

Helloworld:client(“<<Hello>>”).

发出此命令时,将在第一个命令行窗口中显示以下输出。

server received:<<"Hello">>