Ruby提供了对网络服务的两个访问级别。在较低的级别上,您可以访问底层操作系统中的基本Socket支持,从而可以为面向连接和无连接的协议实现客户端和服务器,Ruby还具有提供对特定应用程序级网络协议(如FTP,HTTP等)的更高级别访问的库。
本章将使您对网络-Socket编程中最著名的概念有所了解。
Socket是双向通信通道的端点。Socket可以在一个进程内,同一台机器上的进程之间或不同机器上的进程之间进行通信。
Socket可以通过多种不同的通道类型实现:Unix域Socket,TCP,UDP等。 Socket提供了用于处理常见传输的特定类以及用于处理其余传输的通用接口。
Sr.No. | Term & Remark |
---|---|
1 | domain 用作传输机制的协议族。这些值是常量,如PF_INET,PF_UNIX,PF_X25等。 |
2 | type 两个端点之间的通信类型,通常是面向连接协议的SOCK_STREAM和无连接协议的SOCK_DGRAM。 |
3 | protocol 通常为零,可用于标识域和类型内协议的变体。 |
4 | hostname 主机名 |
5 | port 每台服务器侦听在一个或多个端口上调用的客户端。端口可以是Fixnum端口号,包含端口号的字符串或服务名称。 |
在这里将编写一个非常简单的客户端程序,它将打开到给定端口和给定主机的连接。 Ruby类 TCPSocket 提供了 open 函数来打开这样的Socket。
TCPSocket.open(hosname,port)打开与 port 上 hostname 的TCP连接。
打开Socket后,您可以像读取任何IO对象一样从中读取Socket。完成后,记得关闭它,就像关闭文件一样。
以下代码是一个非常简单的客户端,该客户端连接到给定的主机和端口,从Socket读取任何可用数据,然后退出-
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) 函数来为您的服务指定一个 port 并创建一个 TCPServer 对象。
接下来,调用返回的TCPServer对象的 accept 方法。此方法一直等到客户端连接到您指定的端口,然后返回表示与该客户端连接的 Socket 对象。
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 }
现在,在后台运行此服务器,然后运行上面的客户端以查看输出。
网络上的大多数服务器都设计为可以同时处理大量客户端。
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上以相同的方式运行。
可以使用Socket库来实现任何网络协议。如,这是获取网页内容的代码-
require 'socket' host='www.learnfk.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.learnfk.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库和类方法以查找更多详细信息。
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)