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