Ruby - การเขียนโปรแกรมซ็อกเก็ต
Ruby ให้การเข้าถึงบริการเครือข่ายสองระดับ ในระดับต่ำคุณสามารถเข้าถึงการสนับสนุนซ็อกเก็ตพื้นฐานในระบบปฏิบัติการพื้นฐานซึ่งช่วยให้คุณใช้งานไคลเอนต์และเซิร์ฟเวอร์สำหรับทั้งโปรโตคอลที่เน้นการเชื่อมต่อและไม่มีการเชื่อมต่อ
Ruby ยังมีไลบรารีที่ให้การเข้าถึงระดับที่สูงขึ้นไปยังโปรโตคอลเครือข่ายระดับแอปพลิเคชันเฉพาะเช่น FTP, HTTP และอื่น ๆ
บทนี้จะช่วยให้คุณเข้าใจแนวคิดที่มีชื่อเสียงที่สุดในระบบเครือข่าย - การเขียนโปรแกรมซ็อกเก็ต
ซ็อกเก็ตคืออะไร?
ซ็อกเก็ตเป็นจุดสิ้นสุดของช่องทางการสื่อสารแบบสองทิศทาง ซ็อกเก็ตอาจสื่อสารภายในกระบวนการระหว่างกระบวนการบนเครื่องเดียวกันหรือระหว่างกระบวนการในทวีปต่างๆ
อาจนำซ็อกเก็ตไปใช้กับแชนเนลประเภทต่างๆ: ซ็อกเก็ตโดเมน Unix, TCP, UDP และอื่น ๆ ซ็อกเก็ตให้เรียนที่เฉพาะเจาะจงสำหรับการจัดการระบบขนส่งทั่วไปเช่นเดียวกับอินเตอร์เฟซสำหรับการจัดการทั่วไปส่วนที่เหลือ
Sockets มีคำศัพท์ของตัวเอง -
ซีเนียร์ | ข้อกำหนดและคำอธิบาย |
---|---|
1 | domain ตระกูลของโปรโตคอลที่จะใช้เป็นกลไกการขนส่ง ค่าเหล่านี้เป็นค่าคงที่เช่น PF_INET, PF_UNIX, PF_X25 เป็นต้น |
2 | type ประเภทของการสื่อสารระหว่างปลายทางทั้งสองโดยทั่วไปคือ SOCK_STREAM สำหรับโปรโตคอลที่เน้นการเชื่อมต่อและ SOCK_DGRAM สำหรับโปรโตคอลที่ไม่มีการเชื่อมต่อ |
3 | protocol โดยทั่วไปเป็นศูนย์อาจใช้เพื่อระบุรูปแบบของโปรโตคอลภายในโดเมนและประเภท |
4 | hostname ตัวระบุของอินเทอร์เฟซเครือข่าย - สตริงซึ่งอาจเป็นชื่อโฮสต์ที่อยู่แบบจุด - รูปสี่เหลี่ยมหรือที่อยู่ IPV6 ในสัญกรณ์โคลอน (และอาจเป็นจุด) สตริง "<broadcast>" ซึ่งระบุที่อยู่ INADDR_BROADCAST สตริงที่มีความยาวเป็นศูนย์ซึ่งระบุ INADDR_ANY หรือ จำนวนเต็มตีความเป็นที่อยู่ไบนารีในลำดับไบต์ของโฮสต์ |
5 | port เซิร์ฟเวอร์แต่ละตัวจะรับฟังไคลเอ็นต์ที่เรียกใช้พอร์ตอย่างน้อยหนึ่งพอร์ต พอร์ตอาจเป็นหมายเลขพอร์ต Fixnum สตริงที่มีหมายเลขพอร์ตหรือชื่อของบริการ |
ลูกค้าธรรมดา
ในที่นี้เราจะเขียนโปรแกรมไคลเอนต์ที่เรียบง่ายซึ่งจะเปิดการเชื่อมต่อไปยังพอร์ตที่กำหนดและโฮสต์ที่กำหนด คลาส RubyTCPSocketให้ฟังก์ชันเปิดเพื่อเปิดซ็อกเก็ตดังกล่าว
TCPSocket.open(hosname, port )เปิดเชื่อมต่อ TCP ชื่อโฮสต์บนพอร์ต
เมื่อคุณเปิดซ็อกเก็ตแล้วคุณสามารถอ่านได้เหมือนกับอ็อบเจ็กต์ IO ใด ๆ เมื่อเสร็จแล้วอย่าลืมปิดเช่นเดียวกับที่คุณปิดไฟล์
รหัสต่อไปนี้เป็นไคลเอนต์ที่เรียบง่ายมากที่เชื่อมต่อกับโฮสต์และพอร์ตที่กำหนดอ่านข้อมูลที่มีอยู่จากซ็อกเก็ตจากนั้นออก -
require 'socket' # Sockets are in standard library
hostname = 'localhost'
port = 2000
s = TCPSocket.open(hostname, port)
while line = s.gets # Read lines from the socket
puts line.chop # And print with platform line terminator
end
s.close # Close the socket when done
เซิร์ฟเวอร์ที่เรียบง่าย
ในการเขียนอินเทอร์เน็ตเซิร์ฟเวอร์เราใช้ไฟล์ TCPServerชั้นเรียน อ็อบเจ็กต์ TCPServer เป็นโรงงานสำหรับอ็อบเจ็กต์ TCPSocket
ตอนนี้โทร TCPServer.open(hostname, portเพื่อระบุพอร์ตสำหรับบริการของคุณและสร้างไฟล์TCPServer วัตถุ.
จากนั้นเรียกใช้วิธีการยอมรับของวัตถุ TCPServer ที่ส่งคืน วิธีนี้จะรอจนกว่าไคลเอ็นต์จะเชื่อมต่อกับพอร์ตที่คุณระบุแล้วส่งคืนอ็อบเจ็กต์TCPSocketที่แสดงถึงการเชื่อมต่อกับไคลเอ็นต์นั้น
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
client = server.accept # Wait for a client to connect
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
}
ตอนนี้เรียกใช้เซิร์ฟเวอร์นี้ในพื้นหลังจากนั้นเรียกใช้ไคลเอนต์ด้านบนเพื่อดูผลลัพธ์
เซิร์ฟเวอร์ TCP หลายไคลเอ็นต์
เซิร์ฟเวอร์ส่วนใหญ่บนอินเทอร์เน็ตได้รับการออกแบบมาเพื่อจัดการกับลูกค้าจำนวนมากในคราวเดียว
คลาสเธรดของรูบี้ทำให้การสร้างเซิร์ฟเวอร์มัลติเธรดเป็นเรื่องง่ายหนึ่งที่ยอมรับคำขอและสร้างเธรดการดำเนินการใหม่ทันทีเพื่อประมวลผลการเชื่อมต่อในขณะที่อนุญาตให้โปรแกรมหลักรอการเชื่อมต่อเพิ่มเติม -
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
end
}
ในตัวอย่างนี้คุณมีลูปถาวรและเมื่อ server.accept ตอบสนองเธรดใหม่จะถูกสร้างขึ้นและเริ่มต้นทันทีเพื่อจัดการการเชื่อมต่อที่เพิ่งได้รับการยอมรับโดยใช้อ็อบเจ็กต์การเชื่อมต่อที่ส่งผ่านไปยังเธรด อย่างไรก็ตามโปรแกรมหลักจะวนกลับทันทีและรอการเชื่อมต่อใหม่
การใช้เธรด Ruby ในลักษณะนี้หมายความว่าโค้ดเป็นแบบพกพาและจะทำงานในลักษณะเดียวกันบน Linux, OS X และ Windows
เว็บเบราว์เซอร์ตัวจิ๋ว
เราสามารถใช้ไลบรารีซ็อกเก็ตเพื่อใช้อินเทอร์เน็ตโปรโตคอลใดก็ได้ ตัวอย่างเช่นในที่นี้คือรหัสสำหรับดึงเนื้อหาของหน้าเว็บ -
require 'socket'
host = 'www.tutorialspoint.com' # The web server
port = 80 # Default HTTP port
path = "/index.htm" # The file we want
# This is the HTTP request we send to fetch a file
request = "GET #{path} HTTP/1.0\r\n\r\n"
socket = TCPSocket.open(host,port) # Connect to server
socket.print(request) # Send request
response = socket.read # Read complete response
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2)
print body # And display it
ในการใช้งานเว็บไคลเอ็นต์ที่คล้ายกันคุณสามารถใช้ไลบรารีที่สร้างไว้ล่วงหน้าเช่น Net::HTTPสำหรับการทำงานกับ HTTP นี่คือรหัสที่เทียบเท่ากับรหัสก่อนหน้า -
require 'net/http' # The library we need
host = 'www.tutorialspoint.com' # The web server
path = '/index.htm' # The file we want
http = Net::HTTP.new(host) # Create a connection
headers, body = http.get(path) # Request the file
if headers.code == "200" # Check the status code
print body
else
puts "#{headers.code} #{headers.message}"
end
โปรดตรวจสอบไลบรารีที่คล้ายกันเพื่อทำงานกับโปรโตคอล FTP, SMTP, POP และ IMAP
อ่านเพิ่มเติม
เราได้ให้คุณเริ่มต้นอย่างรวดเร็วในการเขียนโปรแกรมซ็อกเก็ต เป็นเรื่องใหญ่ดังนั้นขอแนะนำให้คุณอ่านRuby Socket Library และ Class Methodsเพื่อดูรายละเอียดเพิ่มเติม