Erlang - พอร์ต
ใน Erlang พอร์ตใช้สำหรับการสื่อสารระหว่างโปรแกรมต่างๆ ซ็อกเก็ตเป็นจุดสิ้นสุดการสื่อสารที่อนุญาตให้เครื่องสื่อสารผ่านอินเทอร์เน็ตโดยใช้ Internet Protocol (IP)
ประเภทของโปรโตคอลที่ใช้ในพอร์ต
มีโปรโตคอล 2 ประเภทสำหรับการสื่อสาร หนึ่งคือ UDP และอีกอันคือ TCP UDP ช่วยให้แอปพลิเคชันสามารถส่งข้อความสั้น ๆ (เรียกว่าดาตาแกรม) ถึงกันได้ แต่ไม่มีการรับประกันว่าจะส่งข้อความเหล่านี้ได้ นอกจากนี้ยังสามารถมาถึงนอกสถานที่ได้ ในทางกลับกัน TCP ให้สตรีมไบต์ที่เชื่อถือได้ซึ่งส่งตามลำดับตราบเท่าที่มีการสร้างการเชื่อมต่อ
มาดูตัวอย่างง่ายๆของการเปิดพอร์ตโดยใช้ UDP
ตัวอย่าง
-module(helloworld).
-export([start/0]).
start() ->
{ok, Socket} = gen_udp:open(8789),
io:fwrite("~p",[Socket]).
สิ่งต่อไปนี้ต้องสังเกตเกี่ยวกับโปรแกรมข้างต้น
gen_udp มีโมดูลใน Erlang ที่ใช้สำหรับการสื่อสาร UDP
8789 คือหมายเลขพอร์ตที่กำลังเปิดใน Erlang คุณต้องแน่ใจว่าหมายเลขพอร์ตนี้พร้อมใช้งานและสามารถใช้ได้
ผลลัพธ์ของโปรแกรมข้างต้นคือ -
#Port<0.376>
การส่งข้อความบนพอร์ต
เมื่อเปิดพอร์ตแล้วสามารถส่งข้อความไปที่พอร์ตได้ ซึ่งทำได้โดยใช้วิธีการส่ง ลองดูไวยากรณ์และตัวอย่างต่อไปนี้
ไวยากรณ์
send(Socket, Address, Port, Packet)
พารามิเตอร์
Socket - นี่คือซ็อกเก็ตที่สร้างด้วยคำสั่ง gen_udp: open
Address - นี่คือที่อยู่เครื่องที่จะต้องส่งข้อความถึง
port - นี่คือพอร์ตที่ไม่จำเป็นต้องส่งข้อความ
Packet - นี่คือรายละเอียดแพ็คเก็ตหรือข้อความที่ต้องส่ง
ส่งคืนค่า
ข้อความตกลงจะถูกส่งกลับหากข้อความถูกส่งอย่างถูกต้อง
ตัวอย่างเช่น
-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 - นี่คือความยาวของข้อความที่ต้องได้รับ
ส่งคืนค่า
ข้อความตกลงจะถูกส่งกลับหากข้อความถูกส่งอย่างถูกต้อง
ตัวอย่างเช่น
-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 หน้าต่าง หน้าต่างแรกจะใช้เพื่อเรียกใช้ส่วนประกอบเซิร์ฟเวอร์โดยเรียกใช้รหัสต่อไปนี้ในไฟล์erl command line window.
helloworld:start().
สิ่งนี้จะแสดงผลลัพธ์ต่อไปนี้ในหน้าต่างบรรทัดคำสั่ง
server opened socket:#Port<0.2314>
ตอนนี้ในหน้าต่างบรรทัดคำสั่ง erl ที่สองให้เรียกใช้คำสั่งต่อไปนี้
Helloworld:client(“<<Hello>>”).
เมื่อคุณออกคำสั่งนี้ผลลัพธ์ต่อไปนี้จะแสดงในหน้าต่างบรรทัดคำสั่งแรก
server received:<<"Hello">>