Erlang - Cổng
Trong Erlang, các cổng được sử dụng để giao tiếp giữa các chương trình khác nhau. Ổ cắm là một điểm cuối giao tiếp cho phép các máy giao tiếp qua Internet bằng cách sử dụng Giao thức Internet (IP).
Các loại giao thức được sử dụng trong các cổng
Có 2 loại giao thức có sẵn để giao tiếp. Một là UDP và một là TCP. UDP cho phép các ứng dụng gửi các tin nhắn ngắn (được gọi là datagram) cho nhau, nhưng không có gì đảm bảo việc gửi các tin nhắn này. Họ cũng có thể đến không theo thứ tự. Mặt khác, TCP cung cấp một luồng byte đáng tin cậy được phân phối theo thứ tự miễn là kết nối được thiết lập.
Hãy xem một ví dụ đơn giản về việc mở một cổng bằng UDP.
Thí dụ
-module(helloworld).
-export([start/0]).
start() ->
{ok, Socket} = gen_udp:open(8789),
io:fwrite("~p",[Socket]).
Những điều sau đây cần lưu ý về chương trình trên
Các gen_udp chứa các mô-đun trong Erlang được sử dụng cho giao tiếp UDP.
Đây 8789 là số cổng đang được mở ở Erlang. Bạn cần đảm bảo rằng số cổng này có sẵn và có thể sử dụng được.
Đầu ra của chương trình trên là:
#Port<0.376>
Gửi tin nhắn trên cổng
Khi cổng đã được mở, một thông báo có thể được gửi trên cổng. Điều này được thực hiện thông qua phương thức gửi. Hãy xem cú pháp và ví dụ sau.
Cú pháp
send(Socket, Address, Port, Packet)
Thông số
Socket - Đây là socket được tạo bằng lệnh gen_udp: open.
Address - Đây là địa chỉ máy để gửi tin nhắn đến.
port - Đây là cổng mà tin nhắn cần được gửi đi.
Packet - Đây là chi tiết gói tin hoặc tin nhắn cần được gửi đi.
Giá trị trả lại
Một tin nhắn ok sẽ được trả lại nếu tin nhắn được gửi đúng cách.
Ví dụ
-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")]).
Đầu ra
Kết quả của chương trình trên sẽ như sau.
#Port<0.376>ok
Nhận tin nhắn trên cổng
Khi cổng đã được mở, một thông báo cũng có thể được nhận trên cổng. Điều này được thực hiện thông quarecv method. Hãy xem cú pháp và ví dụ sau.
Cú pháp
recv(Socket, length)
Thông số
Socket - Đây là socket được tạo bằng lệnh gen_udp: open.
Length - Đây là độ dài của tin nhắn cần được nhận.
Giá trị trả lại
Một tin nhắn ok sẽ được trả lại nếu tin nhắn được gửi đúng cách.
Ví dụ
-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)]).
Chương trình hoàn chỉnh
Rõ ràng là chúng ta không thể có cùng một tin nhắn gửi và nhận trong cùng một chương trình. Bạn cần xác định chúng trong các chương trình khác nhau. Vì vậy, hãy tạo đoạn mã sau để tạo một thành phần máy chủ lắng nghe thông báo và một thành phần máy khách gửi thông báo.
Thí dụ
-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.
Những điều sau đây cần được lưu ý về chương trình trên.
Chúng tôi xác định 2 chức năng, chức năng đầu tiên là máy chủ. Điều này sẽ được sử dụng để lắng nghe trên cổng 4000. Thứ hai là ứng dụng khách sẽ được sử dụng để gửi thông báo “Xin chào” đến thành phần máy chủ.
Vòng lặp nhận được sử dụng để đọc các tin nhắn được gửi trong vòng lặp xác định.
Đầu ra
Bây giờ bạn cần chạy chương trình từ 2 cửa sổ. Cửa sổ đầu tiên sẽ được sử dụng để chạy thành phần máy chủ bằng cách chạy mã sau trongerl command line window.
helloworld:start().
Thao tác này sẽ hiển thị kết quả sau trong cửa sổ dòng lệnh.
server opened socket:#Port<0.2314>
Bây giờ trong cửa sổ dòng lệnh erl thứ hai, hãy chạy lệnh sau.
Helloworld:client(“<<Hello>>”).
Khi bạn phát hành lệnh này, kết quả sau sẽ được hiển thị trong cửa sổ dòng lệnh đầu tiên.
server received:<<"Hello">>