Erlang-ポート

Erlangでは、ポートは異なるプログラム間の通信に使用されます。ソケットは、マシンがインターネットプロトコル(IP)を使用してインターネット経由で通信できるようにする通信エンドポイントです。

ポートで使用されるプロトコルの種類

通信に使用できるプロトコルには2つのタイプがあります。1つはUDPで、もう1つはTCPです。UDPを使用すると、アプリケーションは互いにショートメッセージ(データグラムと呼ばれます)を送信できますが、これらのメッセージの配信は保証されません。彼らはまた、順不同で到着する可能性があります。一方、TCPは、接続が確立されている限り、順番に配信される信頼性の高いバイトストリームを提供します。

UDPを使用してポートを開く簡単な例を見てみましょう。

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

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

上記のプログラムについては、次の点に注意する必要があります。

  • ザ・ gen_udp UDP通信に使用されるErlangのモジュールが含まれています。

  • ここで8789はErlangで開かれているポート番号です。このポート番号が使用可能であり、使用できることを確認する必要があります。

上記のプログラムの出力は次のとおりです。

#Port<0.376>

ポートでメッセージを送信する

ポートが開かれると、メッセージをポートに送信できます。これは、sendメソッドを介して行われます。構文と次の例を見てみましょう。

構文

send(Socket, Address, Port, Packet)

パラメーター

  • Socket −これは、gen_udp:openコマンドで作成されたソケットです。

  • Address −これは、メッセージの送信先となるマシンアドレスです。

  • port −これは、メッセージを送信する必要のあるポート番号です。

  • Packet −これは、送信する必要のあるパケットまたはメッセージの詳細です。

戻り値

メッセージが正しく送信された場合は、okメッセージが返されます。

例えば

-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 method。構文と次の例を見てみましょう。

構文

recv(Socket, length)

パラメーター

  • Socket −これは、gen_udp:openコマンドで作成されたソケットです。

  • Length −これは受信する必要のあるメッセージの長さです。

戻り値

メッセージが正しく送信された場合は、okメッセージが返されます。

例えば

-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), 
Value.

上記のプログラムについては、以下の点に注意する必要があります。

  • 2つの関数を定義します。1つ目はサーバーです。これは、ポート4000でリッスンするために使用されます。2番目は、サーバーコンポーネントにメッセージ「Hello」を送信するために使用されるクライアントです。

  • 受信ループは、定義ループ内で送信されたメッセージを読み取るために使用されます。

出力

次に、2つのウィンドウからプログラムを実行する必要があります。最初のウィンドウは、次のコードを実行してサーバーコンポーネントを実行するために使用されます。erl command line window

helloworld:start().

これにより、コマンドラインウィンドウに次の出力が表示されます。

server opened socket:#Port<0.2314>

次に、2番目のerlコマンドラインウィンドウで、次のコマンドを実行します。

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

このコマンドを発行すると、最初のコマンドラインウィンドウに次の出力が表示されます。

server received:<<"Hello">>