Ruby提供两种级别的网络服务访问.在较低级别,您可以访问底层操作系统中的基本套接字支持,这允许您为面向连接和无连接协议实现客户端和服务器.
Ruby也有库提供对特定应用程序级网络协议的更高级别访问,例如FTP,HTTP等.
本章让您了解Networking&minus中最着名的概念;套接字编程.
什么是套接字?
套接字是双向通信通道的端点.套接字可以在进程内,同一台机器上的进程之间或不同大洲的进程之间进行通信.
套接字可以通过多种不同的通道类型实现:Unix域套接字,TCP, UDP,依此类推. socket 提供了用于处理公共传输的特定类以及用于处理其余传输的通用接口.
套接字有自己的词汇 :
Sr.No. | 术语&说明 |
---|---|
1 | 域 将用作传输机制的协议族.这些值是常量,如PF_INET,PF_UNIX,PF_X25等. |
2 | 类型 两个端点之间的通信类型,通常是面向连接的SOCK_STREAM用于无连接协议的协议和SOCK_DGRAM. |
3 | 协议 通常为零,这可用于识别域内协议的变体并输入. |
4 | 主机名 网络接口的标识符 : 一个字符串,可以是主机名,点分四元组地址,或冒号(可能是点)符号的IPV6地址 字符串"< broadcast>",它指定INADDR_BROADCAST地址. A零长度字符串,指定INADDR_ANY,或 一个整数,在主机中被解释为二进制地址订单. |
5 | 端口 每个服务器侦听在一个或多个端口上呼叫的客户端.端口可以是Fixnum端口号,包含端口号的字符串或服务名称. |
一个简单的客户端
这里我们将编写一个非常简单的客户端程序,它将打开与给定端口和给定主机的连接. Ruby class TCPSocket 提供 open 函数来打开这样的套接字.
TCPSocket.open(hosname,port)在端口上打开与主机名的TCP连接.
打开套接字后,可以从中读取像任何IO对象一样.完成后,请记得关闭它,就像关闭文件一样.
以下代码是一个非常简单的客户端,连接到给定的主机和端口,从套接字读取任何可用的数据,然后退出和减去;
require 'socket' # Sockets are in standard libraryhostname = 'localhost'port = 2000s = TCPSocket.open(hostname, port)while line = s.gets # Read lines from the socket puts line.chop # And print with platform line terminatorends.close # Close the socket when done
简单服务器
要编写Internet服务器,我们使用 TCPServer 类. TCPServer对象是TCPSocket对象的工厂.
现在调用 TCPServer.open(主机名,端口函数指定端口为您的服务并创建 TCPServer 对象.
接下来,调用返回的TCPServer对象的 accept 方法.此方法一直等到客户端连接到您指定的端口,然后返回一个 TCPSocket 对象,该对象表示与该客户端的连接.
require 'socket' # Get sockets from stdlibserver = TCPServer.open(2000) # Socket to listen on port 2000loop { # 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 类可以轻松创建多线程server.one,接受请求并立即创建新的执行线程处理连接,同时允许主程序等待更多连接 :
require 'socket' # Get sockets from stdlibserver = TCPServer.open(2000) # Socket to listen on port 2000loop { # 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.IT屋.com' # The web serverport = 80 # Default HTTP portpath = "/index.htm" # The file we want # This is the HTTP request we send to fetch a filerequest = "GET #{path} HTTP/1.0\r\n\r\n"socket = TCPSocket.open(host,port) # Connect to serversocket.print(request) # Send requestresponse = socket.read # Read complete response# Split response at first blank line into headers and bodyheaders,body = response.split("\r\n\r\n", 2) print body # And display it
要实现类似的Web客户端,您可以使用预构建的库(如 Net :: HTTP )来处理HTTP.这里的代码相当于前面的代码 :
require 'net/http' # The library we needhost = 'www.IT屋.com' # The web serverpath = '/index.htm' # The file we want http = Net::HTTP.new(host) # Create a connectionheaders, body = http.get(path) # Request the fileif headers.code == "200" # Check the status code print body else puts "#{headers.code} #{headers.message}" end
请检查类似的库以使用FTP,SMTP,POP和IMAP协议.
进一步阅读
我们已经为您提供了套接字编程的快速入门.这是一个很大的主题,因此建议您浏览 Ruby套接字库和类方法以查找更多详细信息.