Erlang-ports

提供:Dev Guides
移動先:案内検索

アーラン-ポート

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)

パラメーター

  • ソケット-これはgen_udp:openコマンドで作成されたソケットです。
  • アドレス-これは、メッセージの送信先のマシンアドレスです。
  • ポート-これは、メッセージを送信する必要があるポート番号です。
  • パケット-これは、送信する必要があるパケットまたはメッセージの詳細です。

戻り値

メッセージが適切に送信された場合、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メソッド*を介して行われます。 構文と次の例を見てみましょう。

構文

recv(Socket, length)

パラメーター

  • ソケット-これはgen_udp:openコマンドで作成されたソケットです。
  • 長さ-これは受信する必要があるメッセージの長さです。

戻り値

メッセージが適切に送信された場合、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つの関数を定義します。最初の関数はサーバーです。 これは、ポート4000でリッスンするために使用されます。 2番目は、サーバーコンポーネントにメッセージ「Hello」を送信するために使用されるクライアントです。
  • 受信ループは、定義ループ内で送信されたメッセージを読み取るために使用されます。

出力

次に、2つのウィンドウからプログラムを実行する必要があります。 最初のウィンドウは、* erlコマンドラインウィンドウ*で次のコードを実行することにより、サーバーコンポーネントを実行するために使用されます。

helloworld:start().

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

server opened socket:#Port<0.2314>

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

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

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

server received:<<"Hello">>