Erlang - Porty
W Erlang porty służą do komunikacji między różnymi programami. Gniazdo to punkt końcowy komunikacji, który umożliwia maszynom komunikowanie się przez Internet przy użyciu protokołu internetowego (IP).
Typy protokołów używanych w portach
Do komunikacji dostępne są 2 rodzaje protokołów. Jeden to UDP, a drugi to TCP. Protokół UDP umożliwia aplikacjom wysyłanie do siebie krótkich wiadomości (zwanych datagramami), ale nie ma gwarancji, że te wiadomości zostaną dostarczone. Mogą również przybyć poza kolejnością. Z drugiej strony TCP zapewnia niezawodny strumień bajtów, które są dostarczane w kolejności, o ile połączenie jest ustanowione.
Spójrzmy na prosty przykład otwierania portu za pomocą UDP.
Przykład
-module(helloworld).
-export([start/0]).
start() ->
{ok, Socket} = gen_udp:open(8789),
io:fwrite("~p",[Socket]).
Na temat powyższego programu należy zwrócić uwagę na następujące kwestie
Plik gen_udp zawiera moduły w Erlang używane do komunikacji UDP.
Tutaj 8789 to numer portu, który jest otwierany w Erlang. Musisz upewnić się, że ten numer portu jest dostępny i można go używać.
Wynik powyższego programu to -
#Port<0.376>
Wysyłanie wiadomości w porcie
Po otwarciu portu można na nim wysłać wiadomość. Odbywa się to za pomocą metody wysyłania. Spójrzmy na składnię i następujący przykład.
Składnia
send(Socket, Address, Port, Packet)
Parametry
Socket - To jest gniazdo utworzone za pomocą polecenia gen_udp: open.
Address - To jest adres komputera, na który ma zostać wysłana wiadomość.
port - To jest numer portu, na którym należy wysłać wiadomość.
Packet - To są szczegóły pakietu lub wiadomości, które należy wysłać.
Zwracane wartości
Komunikat ok jest zwracany, jeśli został wysłany poprawnie.
Na przykład
-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")]).
Wynik
Wynik powyższego programu będzie następujący.
#Port<0.376>ok
Odbieranie wiadomości na porcie
Po otwarciu portu można również odebrać wiadomość na porcie. Odbywa się to za pośrednictwemrecv method. Spójrzmy na składnię i następujący przykład.
Składnia
recv(Socket, length)
Parametry
Socket - To jest gniazdo utworzone za pomocą polecenia gen_udp: open.
Length - To jest długość wiadomości, którą należy odebrać.
Zwracane wartości
Komunikat ok jest zwracany, jeśli został wysłany poprawnie.
Na przykład
-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)]).
Kompletny program
Oczywiście nie możemy mieć tej samej wiadomości wysyłającej i odbierającej w tym samym programie. Musisz mieć je zdefiniowane w różnych programach. Stwórzmy więc następujący kod, który tworzy komponent serwera, który nasłuchuje wiadomości, oraz komponent klienta, który wysyła wiadomości.
Przykład
-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.
Na temat powyższego programu należy zwrócić uwagę na następujące kwestie.
Definiujemy 2 funkcje, pierwsza to serwer. Będzie on używany do nasłuchiwania na porcie 4000. Drugi to klient, który zostanie użyty do wysłania wiadomości „Hello” do komponentu serwera.
Pętla odbiorcza służy do odczytywania wiadomości wysyłanych w ramach określonej pętli.
Wynik
Teraz musisz uruchomić program z 2 okien. Pierwsze okno zostanie użyte do uruchomienia składnika serwera, uruchamiając następujący kod werl command line window.
helloworld:start().
Spowoduje to wyświetlenie następujących danych wyjściowych w oknie wiersza poleceń.
server opened socket:#Port<0.2314>
Teraz w drugim oknie wiersza poleceń erl uruchom następujące polecenie.
Helloworld:client(“<<Hello>>”).
Po wydaniu tego polecenia następujące dane wyjściowe zostaną wyświetlone w pierwszym oknie wiersza polecenia.
server received:<<"Hello">>