Ruby - Lập trình Socket

Ruby cung cấp hai cấp độ truy cập vào các dịch vụ mạng. Ở cấp độ thấp, bạn có thể truy cập hỗ trợ socket cơ bản trong hệ điều hành cơ bản, cho phép bạn triển khai các máy khách và máy chủ cho cả giao thức hướng kết nối và không kết nối.

Ruby cũng có các thư viện cung cấp quyền truy cập cấp cao hơn vào các giao thức mạng cấp ứng dụng cụ thể, chẳng hạn như FTP, HTTP, v.v.

Chương này cung cấp cho bạn sự hiểu biết về khái niệm nổi tiếng nhất trong Mạng - Lập trình Socket.

Sockets là gì?

Các ổ cắm là các điểm cuối của một kênh truyền thông hai chiều. Sockets có thể giao tiếp trong một quy trình, giữa các quy trình trên cùng một máy hoặc giữa các quy trình trên các lục địa khác nhau.

Sockets có thể được triển khai trên một số kiểu kênh khác nhau: socket miền Unix, TCP, UDP, v.v. Các ổ cắm cung cấp các lớp cụ thể để xử lý các tàu vận tải thông thường cũng như một giao diện chung để xử lý phần còn lại.

Sockets có từ vựng riêng -

Sr.No. Thuật ngữ & Mô tả
1

domain

Họ các giao thức sẽ được sử dụng làm cơ chế vận chuyển. Các giá trị này là các hằng số như PF_INET, PF_UNIX, PF_X25, v.v.

2

type

Loại giao tiếp giữa hai điểm cuối, thường là SOCK_STREAM cho các giao thức hướng kết nối và SOCK_DGRAM cho các giao thức không kết nối.

3

protocol

Thông thường, giá trị này có thể được sử dụng để xác định một biến thể của giao thức trong một miền và loại.

4

hostname

Định danh của giao diện mạng -

Một chuỗi, có thể là tên máy chủ, địa chỉ có dấu chấm tứ hoặc địa chỉ IPV6 trong ký hiệu dấu hai chấm (và có thể là dấu chấm)

Chuỗi "<broadcast>", chỉ định địa chỉ INADDR_BROADCAST.

Một chuỗi có độ dài bằng 0, chỉ định INADDR_ANY hoặc

Số nguyên, được hiểu là địa chỉ nhị phân theo thứ tự byte máy chủ.

5

port

Mỗi máy chủ lắng nghe các máy khách gọi trên một hoặc nhiều cổng. Một cổng có thể là số cổng Fixnum, một chuỗi chứa số cổng hoặc tên của một dịch vụ.

Một khách hàng đơn giản

Ở đây chúng ta sẽ viết một chương trình khách rất đơn giản, chương trình này sẽ mở một kết nối đến một cổng nhất định và máy chủ nhất định. Lớp RubyTCPSocketcung cấp chức năng mở để mở một ổ cắm như vậy.

Các TCPSocket.open(hosname, port )mở kết nối TCP tới tên máy chủ trên cổng .

Khi bạn đã mở một ổ cắm, bạn có thể đọc từ đó giống như bất kỳ đối tượng IO nào. Khi hoàn tất, hãy nhớ đóng nó, vì bạn sẽ đóng một tệp.

Đoạn mã sau là một ứng dụng khách rất đơn giản kết nối với một máy chủ và cổng nhất định, đọc bất kỳ dữ liệu nào có sẵn từ ổ cắm, sau đó thoát ra -

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

Một máy chủ đơn giản

Để viết máy chủ Internet, chúng tôi sử dụng TCPServerlớp học. Đối tượng TCPServer là một nhà máy cho các đối tượng TCPSocket.

Gọi ngay TCPServer.open(hostname, portchức năng chỉ định một cổng cho dịch vụ của bạn và tạoTCPServer vật.

Tiếp theo, gọi phương thức chấp nhận của đối tượng TCPServer được trả về. Phương thức này đợi cho đến khi một máy khách kết nối với cổng bạn đã chỉ định, rồi trả về một đối tượng TCPSocket đại diện cho kết nối với máy khách đó.

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
}

Bây giờ, chạy máy chủ này ở chế độ nền và sau đó chạy ứng dụng khách trên để xem kết quả.

Máy chủ TCP đa máy khách

Hầu hết các máy chủ trên Internet được thiết kế để xử lý số lượng lớn khách hàng cùng một lúc.

Lớp Thread của Ruby giúp dễ dàng tạo một máy chủ đa luồng chấp nhận các yêu cầu và ngay lập tức tạo một luồng thực thi mới để xử lý kết nối trong khi vẫn cho phép chương trình chính chờ đợi nhiều kết nối hơn -

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
}

Trong ví dụ này, bạn có một vòng lặp vĩnh viễn và khi server.accept phản hồi, một luồng mới sẽ được tạo và bắt đầu ngay lập tức để xử lý kết nối vừa được chấp nhận, bằng cách sử dụng đối tượng kết nối được truyền vào luồng. Tuy nhiên, chương trình chính ngay lập tức lặp lại và chờ các kết nối mới.

Sử dụng các chuỗi Ruby theo cách này có nghĩa là mã có thể di động và sẽ chạy theo cùng một cách trên Linux, OS X và Windows.

Trình duyệt web nhỏ

Chúng ta có thể sử dụng thư viện socket để triển khai bất kỳ giao thức Internet nào. Ví dụ ở đây là một đoạn mã để tìm nạp nội dung của một trang web -

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

Để triển khai ứng dụng khách web tương tự, bạn có thể sử dụng thư viện được tạo sẵn như Net::HTTPđể làm việc với HTTP. Đây là mã tương đương với mã trước đó -

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

Vui lòng kiểm tra các thư viện tương tự để hoạt động với các giao thức FTP, SMTP, POP và IMAP.

Đọc thêm

Chúng tôi đã cung cấp cho bạn một khởi đầu nhanh về Lập trình Socket. Đây là một chủ đề lớn, vì vậy bạn nên đi qua Thư viện Ruby Socket và Phương thức lớp để tìm thêm chi tiết.