English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ports (Port) in Erlang

In Erlang, ports are used for communication between different programs. A socket is a communication endpoint that allows a computer to communicate over the Internet using the Internet Protocol (IP).

The protocol type used in the port

There are two protocols available for communication. One is UDP, and the other is TCP. UDP allows applications to send short messages to each other (known as datagrams), but it does not guarantee the delivery of these messages. They may also fail. On the other hand, TCP provides a reliable byte stream, and as long as the connection is established, these bytes are passed in order.

Let's look at a simple example of opening a port using UDP.

Instance

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

Output

The output of the above program is as follows.

#Port<0.376>ok

Receiving messages on the port

After the port is opened, a message can still be received on the port. This is done through the recv method. Let's look at the syntax and the following example.

Syntax

recv(Socket, length)

Parameters

  • Socket This is a socket created using the gen_udp:open command.

  • Length −This is the length of the message that needs to be received.

Return Value

if the message is sent correctly, then return the confirmation message.

For example

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

Complete Program

Now it is obvious that we cannot have the same send and receive messages in the same program. You need to define them in different programs. Therefore, let's create the following code, which creates a listening message server component and a sending message client component.

Instance

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

The following points should be noted about the above program.

  • We have defined two functions, the first one is the server function. This will be used to listen on the port4000. The second is the client, which will be used to send the message "Hello" to the server component.

  • The receive loop is used to read messages sent within the defined loop.

Output

Now you need to run the program from both windows. The first window will run the server component by running the following code in the Erlang command line window.

helloworld:start().

The following output will be displayed in the command line window.

server opened socket:#Port<0.2314>

Now, run the following command in the second Erlang command line window.

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

The following output will be displayed in the first command line window when this command is issued.

server received:<<"Hello">>