Ruby通訊端程式設計(Socket)


通訊端是網路通訊通道的端點,用戶端和伺服器之間相互通訊。它們可以在同一台機器上或在不同的機器上進行通訊。

通訊端(Socket)的型別有以下幾種:

  • TCP通訊端
  • UDP通訊端
  • UNIX通訊端

有兩個級別的通訊端 - 高階和低階。 低階存取允許您處理系統支援的通訊端。 它允許實現無連線和面向連線的協定。 高階存取允許您處理像HTTP和FTP這樣的網路協定。

範例-1

建立一個伺服器端 - server1.rb,程式碼如下 -

#!/usr/bin/ruby   
# file : server1.rb

require 'socket'   

server = TCPServer.open(8088)   
loop {   
    client = server.accept   
    client.puts "Hello. This is socket programming"   
    client.close   
}

在上述程式碼中,需要包括預先安裝的socket模組。 在系統上使用8088埠。當然您可根據需要可以使用任何其它的埠。

啟動迴圈,接受所有連線到8088埠,並通過通訊端網路將資料傳送給用戶端。

最後,關閉通訊端。

建立一個用戶端程式碼 - client1.rb

#!/usr/bin/ruby   
# file : client1.rb
require 'socket'   

hostname = 'localhost'   
port = 8088   

s = TCPSocket.open(hostname, port)   

while line = s.gets   
    puts line.chomp   
end   
s.close

在上述程式碼中,需要包括預先安裝的socket模組。 建立一個通訊端並將其連線到埠8088

建立一個while迴圈來獲取通過通訊端傳送的所有資訊。

最後,關閉通訊端。

執行輸出:

開啟終端,轉到儲存上述兩個檔案的目錄,在本範例中,所有程式碼均儲存在:F:\worksp\ruby 目錄下。

現在開啟兩個終端。在第一個終端先執行伺服器指令碼(ruby server1.rb),伺服器指令碼啟動完成後,在第二個終端執行以下命令執行用戶端指令碼,得到以下結果 -

F:\worksp\ruby>ruby client1.rb
Hello. This is socket programming

F:\worksp\ruby>

多個用戶端通訊端程式設計

對於多個用戶端進行通訊端程式設計,將需要一個迴圈和一些執行緒來接受和響應多個用戶端連線和互動。

範例-2

建立一個伺服器端 - server2.rb,程式碼如下 -

#!/usr/bin/env ruby -w
# file : server2.rb

require "socket"   
class Server   
  def initialize( port, ip )   
    @server = TCPServer.open( ip, port )   
    @connections = Hash.new   
    @rooms = Hash.new   
    @clients = Hash.new   
    @connections[:server] = @server   
    @connections[:rooms] = @rooms   
    @connections[:clients] = @clients   
    run   
  end   

  def run   
    loop {   
      Thread.start(@server.accept) do | client |   
        nick_name = client.gets.chomp.to_sym   
        @connections[:clients].each do |other_name, other_client|   
          if nick_name == other_name || client == other_client   
            client.puts "This username already exist"   
            Thread.kill self   
          end   
        end   
        puts "#{nick_name} #{client}"   
        @connections[:clients][nick_name] = client   
        client.puts "Connection established..."   
        listen_user_messages( nick_name, client )   
      end   
    }.join   
  end   

  def listen_user_messages( username, client )   
    loop {   
      msg = client.gets.chomp   
      @connections[:clients].each do |other_name, other_client|   
        unless other_name == username   
          other_client.puts "#{username.to_s}: #{msg}"   
        end   
      end   
    }   
  end   
end   

Server.new( 8088, "localhost" )

在上面的程式碼中,伺服器將與用戶端在指定的埠(8088)來建立連線。 在這裡,每個連線的使用者需要一個執行緒來處理使用者連線資訊互動。

run方法驗證輸入的名稱是否唯一。 如果使用者名已經存在,連線將被斷開,否則將建立連線。

listen_user_messages方法用於偵聽使用者訊息並將其傳送給所有使用者。

建立一個用戶端程式碼 - client2.rb

#!/usr/bin/env ruby -w
# file : client2.rb

require "socket"   
class Client   
  def initialize( server )   
    @server = server   
    @request = nil   
    @response = nil   
    listen   
    send   
    @request.join   
    @response.join   
  end   

  def listen   
    @response = Thread.new do   
      loop {   
        msg = @server.gets.chomp   
        puts "#{msg}"   
      }   
    end   
  end   

  def send   
    puts "Enter your name:"   
    @request = Thread.new do   
      loop {   
        msg = $stdin.gets.chomp   
        @server.puts( msg )   
      }   
    end   
  end   
end   

server = TCPSocket.open( "localhost", 8088 )   
Client.new( server )

在上面的程式碼中,建立了Client類用來處理使用者。

sendlisten 方法中建立兩個執行緒,以便可以同時讀取/寫入訊息。

執行輸出:

下面顯示兩個用戶端之間的聊天訊息,首先執行(ruby server2.rb),然後再執行兩個用戶端,在兩個用戶端之間傳送資訊聊天。

伺服器(server2.rb)記錄每個用戶端連線資訊 -

F:\worksp\ruby>ruby server2.rb
maxsu #<TCPSocket:0x00000002c3dc30>
minsu #<TCPSocket:0x00000002c3d730>
......