คุณต้องการสร้าง network clients และ servers แบบกำหนดเองใน Ruby ใช่ไหม? หรือเพียงแค่อยากเข้าใจว่ามันทำงานอย่างไร?
คุณจะต้องจัดการกับ sockets ครับ
มาร่วมเดินทางสำรวจ การเขียนโปรแกรมเครือข่าย Ruby เพื่อเรียนรู้พื้นฐาน และเริ่มสื่อสารกับ servers และ clients อื่นๆ โดยใช้ Ruby กันเถอะ!
Sockets คืออะไร?
Sockets คือจุดปลายทางของช่องทางการสื่อสาร ทั้ง clients และ servers ใช้ sockets เพื่อแลกเปลี่ยนข้อมูล
หลักการทำงานง่ายมาก:
เมื่อการเชื่อมต่อถูกสร้างขึ้น คุณสามารถส่งข้อมูลเข้าไปใน socket และข้อมูลจะไปถึงปลายทางอีกข้างหนึ่ง โดยฝั่งรับจะอ่านข้อมูลจาก socket เพื่อประมวลผลข้อมูลที่เข้ามา
ประเภทของ Sockets
มีหลายประเภทของ sockets ให้เลือกใช้ โดยที่พบบ่อยที่สุดคือ TCP Socket — จะช่วยให้คุณเชื่อมต่อกับบริการที่ใช้ TCP เช่น HTTP หรือ FTP
หากต้องใช้โปรโตคอลที่ใช้ UDP สามารถใช้ UDP Socket ได้
ประเภทอื่นๆ ค่อนข้างเฉพาะทาง เช่น Unix sockets ใช้สำหรับ IPC (Inter-process communication) ในระบบ Unix โดยไม่ต้องมี overhead ของการเชื่อมต่อ TCP แบบเต็มรูปแบบ
การใช้ Sockets ใน Ruby
ตอนนี้เรารู้ว่า sockets ทำอะไรได้บ้าง เริ่มใช้งานกันเลย
ขั้นแรก ให้ require library sockets เข้าโปรแกรม:
require 'socket'
เพื่อสร้าง TCP socket ให้ใช้ class TCPSocket โดยระบุ IP address และ port ของปลายทาง
คำสั่งนี้จะพยายามสร้างการเชื่อมต่อ หากไม่สำเร็จ จะได้ error Errno::ECONNREFUSED
socket = TCPSocket.new('google.com', 80) ตอนนี้คุณส่งข้อความผ่าน socket ได้แล้ว แต่ต้องปฏิบัติตามโปรโตคอลที่สื่อสารอยู่ เพื่ออีกฝั่งจะเข้าใจ
socket.write "GET / HTTP/1.1" socket.write "\r\n\r\n"
หลายเมธอดที่จะใช้มาจาก parent classes ของ TCPSocket

เพื่ออ่าน response จาก server ใช้เมธอด recv
ต้องระบุจำนวน bytes ที่ต้องการอ่านจาก socket:
puts socket.recv(100)
มีปัญหาเล็กน้อย: อาจไม่ได้ข้อมูลกลับมา ทำให้โปรแกรมดูเหมือนค้าง
เหตุผลคือ หากยังไม่มีข้อมูลพอที่จะอ่าน โปรแกรมจะ block
หมายถึง จะรอจนกว่าจะมีข้อมูลหรือ server ปิดการเชื่อมต่อ
อาจต้องเพิ่มหรือลดปริมาณข้อมูลที่อ่าน ขึ้นกับโปรโตคอลที่ใช้งาน
หาก blocking เป็นปัญหา ลองดูเมธอด readpartial และ read_nonblock จาก class IO
วิธีเขียน TCP Server
มาสร้าง server กัน! ขั้นตอนคล้าย client แต่ต้องบอก socket ให้ bind ไปที่ interface แล้ว listen และสุดท้าย accept การเชื่อมต่อที่เข้ามา
Class TCPServer ทำ 2 ขั้นตอนแรกให้โดยอัตโนมัติ
ตัวอย่าง:
require 'socket' socket = TCPServer.new('0.0.0.0', 8080) client = socket.accept puts "New client! #{client}" client.write("Hello from server") client.close Server ตัวอย่างนี้จะ listen ที่ port 8080 และทักทาย client ที่เชื่อมต่อด้วยข้อความ
สังเกตว่า รับ client ได้เพียงตัวเดียว โปรแกรมจะจบทำงานทันที
รองรับ Multiple Clients
เพื่อรับและตอบสนองหลาย clients พร้อมกัน ต้องใช้ loop และ threads
ตัวอย่าง:
require 'socket' PORT = 8081 socket = TCPServer.new('0.0.0.0', PORT) def handle_connection(client) puts "New client! #{client}" client.write("Hello from server") client.close end puts "Listening on #{PORT}. Press CTRL+C to cancel." loop do client = socket.accept Thread.new { handle_connection(client) } end Server นี้จะ listen ต่อเนื่องจนกว่าคุณจะหยุดมัน
อยากเรียนรู้ต่อยอดไปสร้าง web server ใน Ruby? อ่านบล็อกโพสต์นี้ต่อได้เลย
สรุป
คุณเรียนรู้ว่า TCP sockets คืออะไร ทำงานอย่างไร และใช้ class TCPServer กับ TCPSocket สร้างแอป Ruby ที่สื่อสารกับเครื่องอื่นบนอินเทอร์เน็ตได้
การเล่นกับ Ruby network programming สนุกมาก!
ไป สร้างสิ่งน่าสนใจแล้วแชร์ในส่วนความคิดเห็น กันเถอะ 🙂
อย่าลืมสมัครรับ newsletter ของผม ถ้าอยากพัฒนาทักษะ Ruby ต่อไป!