English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby Socket Programming

Ruby bietet zwei Ebenen der Netzwerkzugriffsdienste an, auf der unteren Ebene können Sie auf das Betriebssystem zugreifen, das Ihnen ermöglicht, Client- und Server-Endpunkte für verbindungsorientierte und verbindungsfreie Protokolle zu unterstützen.

Ruby unterstützt einheitlich Netzwerkprotokolle von Anwendungen, wie z.B. FTP, HTTP.

Ob hoch- oder tiefste Ebene. Ruby bietet einige grundlegende Klassen, mit denen Sie viele Protokolle wie TCP, UDP, SOCKS interagieren können, ohne sich an der Netzwerkebene festzuhalten. Diese Klassen bieten auch Hilfsklassen, die es Ihnen erleichtern, Server zu lesen und zu schreiben.

Lassen Sie uns nun lernen, wie man Ruby Socket-Programmierung durchführt

Was sind Sockets

Während der Datenkommunikation der Anwendungsschicht über die Transportschicht werden TCP und UDP mit dem Problem konfrontiert, gleichzeitig für mehrere Anwendungsvorgänge zu konkurrieren. Mehrere TCP-Verbindungen oder mehrere Anwendungsvorgänge könnten Daten über denselben TCP-Protokollport übertragen müssen. Um verschiedene Anwendungsvorgänge und Verbindungen zu unterscheiden, bieten viele Betriebssysteme für die Interaktion von Anwendungen mit dem TCP/IP-Protokoll eine Schnittstelle namens Socket, um die Netzwerkommunikation und Verbindungen zwischen verschiedenen Anwendungsvorgängen zu unterscheiden.

Durch die Erstellung eines Sockets, hauptsächlich3Diese Parameter: die IP-Adresse des Kommunikationsziels, das verwendete Transportschichtprotokoll (TCP oder UDP) und der verwendete Port.3Diese Parameter zusammengefasst, werden mit einem "Stecker" Socket verbunden, so dass die Anwendungsschicht über das Socket-Interface die Datenübertragung konkurrieren kann, die von verschiedenen Anwendungsvorgängen oder Netzwerkverbindungen kommt, und den parallelen Dienst der Datenübertragung realisieren kann.

Wörterbucherklärung von Sockets:

OptionenBeschreibung
DomainKennzeichnet die verwendete Protokollfamilie, normalerweise PF_INET, PF_UNIX, PF_X25, usw.
TypeSpezifiziert den Typ des Sockets: SOCK_STREAM oder SOCK_DGRAM. Der Socket-Interface definiert auch den Raw-Socket (SOCK_RAW), der es Programmen ermöglicht, niedrigeren Protokollen zu verwenden.
ProtocolNormalerweise wird 0 zugewiesen.
HostnameDer Bezeichner des Netzwerkinterfaces:
  • Ein String, der entweder den Hostnamen oder die IP-Adresse sein kann.

  • Der String "<broadcast>", der die INADDR_BROADCAST-Adresse spezifiziert.

  • Eine 0-Länge Zeichenkette, die INADDR_ANY spezifiziert.

  • Ein Integer, der die binäre Adresse im Hostbyte-Reihenfolge darstellt.

PortPort ist die Nummer des Ports, jeder Server überwacht eine oder mehrere Portnummern für Client-Verbindungen. Ein Port kann die Nummer eines Fixnum sein, die den Hostnamen und den Port enthält.

Einfaches Client-Beispiel

Hier erstellen wir durch die Angabe eines Hosts und Ports ein einfaches Client-Beispiel. Die Ruby TCPSocket-Klasse bietet die open-Methode, um einen Socket zu öffnen.

TCPSocket.open(hostname, port) 打开一个 TCP 连接。

一旦你打开一个 Socket 连接,你可以像 IO 对象一样读取它,完成后,你需要像关闭文件一样关闭该连接。

以下示例演示了如何连接到一个指定的主机,并从 socket 中读取数据,最后关闭 socket:

Online-Beispiel

require 'socket' # Sockets 是标准库
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets # 从 socket 中读取每行数据
  puts line.chop # 打印到终端
end
s.close # 关闭 socket

简单的服务

Ruby 中可以使用 TCPServer 类来编写简单的服务。TCPServer 对象是 TCPSocket 的工厂对象。

现在我们使用 TCPServer.open(hostname, port) 来创建一个 TCPServer 对象。

接下来调用 TCPServer 的 accept 方法,该方法会等待一个客户端连接到指定的端口,然后返回一个 TCPSocket 对象,表示连接到该客户端。

Online-Beispiel

require 'socket' # Socket 标准库获取
 
server = TCPServer.open(2000) # Socket 监听端口为 2000
loop { # 永久运行服务
  client = server.accept # 等待客户端连接
  client.puts(Time.now.ctime) # 将时间发送到客户端
  client.puts "Die Verbindung wird geschlossen. Auf Wiedersehen!"
  client.close # 关闭客户端连接
}

现在,在服务器上运行以上代码,查看效果。

多客户端 TCP 服务

在互联网上,大多数服务都有大量的客户端连接。

Ruby 的 Thread 类可以轻松地创建多线程服务,一个线程处理客户端的连接,而主线程则等待更多的连接。

Online-Beispiel

require 'socket' # Socket 标准库获取
 
server = TCPServer.open(2000) # Socket hört auf Port 2000
loop { # Dauerhaft laufender Service
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # Senden der Zeit an den Client
    client.puts "Die Verbindung wird geschlossen. Auf Wiedersehen!"
    client.close # Schließen der Client-Verbindung
  end
}

In diesem Beispiel läuft der Socket dauerhaft, und wenn server.accept eine Verbindung vom Client erhält, wird ein neuer Thread erstellt und beginnt sofort, die Anfrage zu bearbeiten. Der Hauptprogramm kehrt sofort in die Schleife zurück und wartet auf neue Verbindungen.

Kleiner Web-Browser

Wir können die Bibliothek socket verwenden, um jeden Internet-Protokoll zu realisieren. Der folgende Code zeigt, wie man den Inhalt einer Webseite abruft:

Online-Beispiel

require 'socket'
 
host = 'de.oldtoolbag.com' # Webserver
port = 80 # Standard-HTTP-Port
path = "/index.htm" # Die Adresse der Datei, die abgerufen werden soll
 
# Dies ist eine HTTP-Anfrage
request = "GET #{path} HTTP/1.0\r\n\r\n"
 
socket = TCPSocket.open(host,port) # Verbindung zum Server herstellen
socket.print(request) # Senden der Anfrage
response = socket.read # Lesen der vollständigen Antwort
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2) 
print body # Ausgabeergebnis

Um einen ähnlichen Web-Client zu realisieren, können Sie Bibliotheken wie Net::HTTP verwenden, die für HTTP vorausbereitet sind.

Der folgende Code ist äquivalent zum vorherigen Code:

Online-Beispiel

require 'net/http' # wir benötigten Bibliotheken
host = 'de.oldtoolbag.com'           # web server
path = '/index.htm'                 # The file we want 
 
http = Net::HTTP.new(host)          # Create connection
headers, body = http.get(path)      # Request file
if headers.code == "200"            # Check status code
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end

In this section, we simply introduce the application of Ruby sockets, for more documentation please see:Ruby Socket Library and Class Methods