Erlang - Porti

In Erlang, le porte vengono utilizzate per la comunicazione tra diversi programmi. Un socket è un endpoint di comunicazione che consente alle macchine di comunicare su Internet utilizzando il protocollo Internet (IP).

Tipi di protocolli utilizzati nelle porte

Sono disponibili 2 tipi di protocolli per la comunicazione. Uno è UDP e l'altro è TCP. UDP consente alle applicazioni di inviare brevi messaggi (chiamati datagrammi) l'un l'altro, ma non vi è alcuna garanzia di consegna per questi messaggi. Possono arrivare anche fuori servizio. TCP, d'altra parte, fornisce un flusso affidabile di byte che vengono consegnati in ordine finché viene stabilita la connessione.

Diamo un'occhiata a un semplice esempio di apertura di una porta utilizzando UDP.

Esempio

-module(helloworld). 
-export([start/0]). 

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

Le seguenti cose devono essere annotate sul programma di cui sopra

  • Il gen_udp contiene i moduli in Erlang utilizzati per la comunicazione UDP.

  • Qui 8789 è il numero di porta che viene aperto a Erlang. È necessario assicurarsi che questo numero di porta sia disponibile e possa essere utilizzato.

L'output del programma di cui sopra è:

#Port<0.376>

Invio di un messaggio sul porto

Una volta aperta la porta, è possibile inviare un messaggio sulla porta. Questo viene fatto tramite il metodo di invio. Diamo un'occhiata alla sintassi e al seguente esempio.

Sintassi

send(Socket, Address, Port, Packet)

Parametri

  • Socket - Questo è il socket creato con il comando gen_udp: open.

  • Address - Questo è l'indirizzo della macchina a cui deve essere inviato il messaggio.

  • port - Questa è la porta no su cui il messaggio deve essere inviato.

  • Packet - Questi sono i dettagli del pacchetto o del messaggio che devono essere inviati.

Valori restituiti

Viene restituito un messaggio ok se il messaggio è stato inviato correttamente.

Per esempio

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

Produzione

L'output del programma di cui sopra sarà il seguente.

#Port<0.376>ok

Ricezione di un messaggio sul porto

Una volta aperta la porta, è possibile ricevere un messaggio anche sulla porta. Questo viene fatto tramiterecv method. Diamo un'occhiata alla sintassi e al seguente esempio.

Sintassi

recv(Socket, length)

Parametri

  • Socket - Questo è il socket creato con il comando gen_udp: open.

  • Length - Questa è la lunghezza del messaggio che deve essere ricevuto.

Valori restituiti

Viene restituito un messaggio ok se il messaggio è stato inviato correttamente.

Per esempio

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

Il programma completo

Ora ovviamente non possiamo avere lo stesso messaggio di invio e ricezione nello stesso programma. È necessario averli definiti in diversi programmi. Quindi creiamo il seguente codice che crea un componente server che ascolta i messaggi e un componente client che invia i messaggi.

Esempio

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

Le seguenti cose devono essere annotate sul programma di cui sopra.

  • Definiamo 2 funzioni, la prima è server. Questo verrà utilizzato per l'ascolto sulla porta 4000. Il secondo è il client che verrà utilizzato per inviare il messaggio "Hello" al componente server.

  • Il ciclo di ricezione viene utilizzato per leggere i messaggi inviati all'interno di un ciclo di definizione.

Produzione

Ora devi eseguire il programma da 2 finestre. La prima finestra verrà utilizzata per eseguire il componente server eseguendo il codice seguente nel fileerl command line window.

helloworld:start().

Questo visualizzerà il seguente output nella finestra della riga di comando.

server opened socket:#Port<0.2314>

Ora nella seconda finestra della riga di comando erl, esegui il seguente comando.

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

Quando si immette questo comando, il seguente output verrà visualizzato nella prima finestra della riga di comando.

server received:<<"Hello">>