📜  Ruby-套接字编程

📅  最后修改于: 2020-10-16 06:02:38             🧑  作者: Mango


Ruby提供了对网络服务的两个访问级别。在较低的级别上,您可以访问底层操作系统中的基本套接字支持,从而可以为面向连接和无连接的协议实现客户端和服务器。

Ruby还具有提供对特定应用程序级网络协议(例如FTP,HTTP等)的更高级别访问的库。

本章将使您对网络-套接字编程中最著名的概念有所了解。

什么是插座?

套接字是双向通信通道的端点。套接字可以在一个进程内,同一台机器上的进程之间或不同大陆上的进程之间进行通信。

套接字可以通过许多不同的通道类型实现:Unix域套接字,TCP,UDP等。套接字提供用于处理公共传输的特定类以及用于处理其余部分的通用接口。

套接字有自己的词汇表-

Sr.No. Term & Description
1

domain

The family of protocols that will be used as the transport mechanism. These values are constants such as PF_INET, PF_UNIX, PF_X25, and so on.

2

type

The type of communications between the two endpoints, typically SOCK_STREAM for connection-oriented protocols and SOCK_DGRAM for connectionless protocols.

3

protocol

Typically zero, this may be used to identify a variant of a protocol within a domain and type.

4

hostname

The identifier of a network interface −

A string, which can be a host name, a dotted-quad address, or an IPV6 address in colon (and possibly dot) notation

A string “”, which specifies an INADDR_BROADCAST address.

A zero-length string, which specifies INADDR_ANY, or

An Integer, interpreted as a binary address in host byte order.

5

port

Each server listens for clients calling on one or more ports. A port may be a Fixnum port number, a string containing a port number, or the name of a service.

一个简单的客户

在这里,我们将编写一个非常简单的客户端程序,该程序将打开到给定端口和给定主机的连接。 Ruby类TCPSocket提供了打开函数来打开这样的套接字。

TCPSocket.open(hosname,port)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

一个简单的服务器

要编写Internet服务器,我们使用TCPServer类。 TCPServer对象是TCPSocket对象的工厂。

现在调用TCPServer.open(hostname,port函数)为您的服务指定一个端口并创建一个TCPServer对象。

接下来,调用返回的TCPServer对象的accept方法。此方法一直等到客户端连接到您指定的端口,然后返回一个表示与该客户端的连接的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服务器

Internet上的大多数服务器都设计为可以同时处理大量客户端。

Ruby的Thread类使创建多线程服务器变得容易。一个服务器接受请求并立即创建一个新的执行线程来处理连接,同时允许主程序等待更多连接-

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上以相同的方式运行。

微型Web浏览器

我们可以使用套接字库来实现任何Internet协议。例如,这是获取网页内容的代码-

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

要实现类似的Web客户端,您可以使用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协议。

进一步阅读

我们为您提供了有关Socket编程的快速入门。这是一个很大的主题,因此建议您遍历Ruby Socket库和类方法以找到更多详细信息。