Erlang - Portos

Em Erlang, as portas são usadas para comunicação entre diferentes programas. Um soquete é um ponto de extremidade de comunicação que permite que as máquinas se comuniquem pela Internet usando o protocolo da Internet (IP).

Tipos de protocolos usados ​​em portas

Existem 2 tipos de protocolos disponíveis para comunicação. Um é UDP e o outro é TCP. O UDP permite que os aplicativos enviem mensagens curtas (chamadas de datagramas) entre si, mas não há garantia de entrega dessas mensagens. Eles também podem chegar fora de serviço. O TCP, por outro lado, fornece um fluxo confiável de bytes que são entregues em ordem, desde que a conexão seja estabelecida.

Vejamos um exemplo simples de abertura de uma porta usando UDP.

Exemplo

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

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

As seguintes coisas precisam ser observadas sobre o programa acima

  • o gen_udp contém os módulos em Erlang usados ​​para comunicação UDP.

  • Aqui, 8789 é o número da porta que está sendo aberta em Erlang. Você precisa ter certeza de que este número de porta está disponível e pode ser usado.

O resultado do programa acima é -

#Port<0.376>

Envio de mensagem no porto

Assim que a porta for aberta, uma mensagem pode ser enviada na porta. Isso é feito por meio do método send. Vejamos a sintaxe e o exemplo a seguir.

Sintaxe

send(Socket, Address, Port, Packet)

Parâmetros

  • Socket - Este é o socket criado com o comando gen_udp: open.

  • Address - Este é o endereço da máquina para onde a mensagem deve ser enviada.

  • port - Este é o número da porta em que a mensagem deve ser enviada.

  • Packet - Estes são os detalhes do pacote ou mensagem que devem ser enviados.

Valores Retornados

Uma mensagem ok é retornada se a mensagem foi enviada corretamente.

Por exemplo

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

Resultado

A saída do programa acima será a seguinte.

#Port<0.376>ok

Recebendo uma mensagem no porto

Assim que a porta for aberta, uma mensagem também pode ser recebida na porta. Isso é feito por meio dorecv method. Vejamos a sintaxe e o exemplo a seguir.

Sintaxe

recv(Socket, length)

Parâmetros

  • Socket - Este é o socket criado com o comando gen_udp: open.

  • Length - Este é o comprimento da mensagem que deve ser recebida.

Valores Retornados

Uma mensagem ok é retornada se a mensagem foi enviada corretamente.

Por exemplo

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

O Programa Completo

Obviamente, não podemos ter a mesma mensagem de envio e recebimento no mesmo programa. Você precisa defini-los em diferentes programas. Portanto, vamos criar o seguinte código que cria um componente de servidor que escuta as mensagens e um componente de cliente que envia mensagens.

Exemplo

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

As seguintes coisas precisam ser observadas sobre o programa acima.

  • Definimos 2 funções, a primeira é servidor. Isso será usado para escutar na porta 4000. O segundo é o cliente que será usado para enviar a mensagem “Olá” ao componente do servidor.

  • O loop de recepção é usado para ler as mensagens enviadas dentro de um loop de definição.

Resultado

Agora você precisa executar o programa em 2 janelas. A primeira janela será usada para executar o componente do servidor executando o seguinte código noerl command line window.

helloworld:start().

Isso exibirá a seguinte saída na janela da linha de comando.

server opened socket:#Port<0.2314>

Agora, na segunda janela da linha de comando erl, execute o seguinte comando.

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

Ao emitir este comando, a seguinte saída será exibida na primeira janela da linha de comando.

server received:<<"Hello">>