English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Порты (Port) Erlang

В Erlang порты используются для通信 между различными программами. Сокет — это точка подключения для通信, который позволяет компьютерам использовать протокол Интернета (IP) для通信 через Интернет.

Тип протокола, используемого в порту

Для通信可以使用 два протокола. Один из них — 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), 
Значение.

О программе, упомянутой выше,应注意以下几点.

  • Мы определили две функции. Первая - функция сервера. Она будет использоваться для мониторинга порта 4000. Вторая - клиент, который будет использоваться для отправки сообщения "Hello" компоненту сервера.

  • Цикл приема используется для чтения сообщений, отправленных в определенном цикле.

Вывод

Теперь вам нужно запустить программу из двух окон. В первом окне выполните следующий код, чтобы запустить компонент сервера.

helloworld:start().

Следующий вывод будет отображен в окне командной строки.

сервер открыл сокет:#Port<0.2314>

Теперь, в втором окне командной строки erl, выполните следующую команду.

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

Когда вы отправляете этот команду, следующий вывод будет отображен в первом окне командной строки.

сервер получил:<<"Hello">>