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>
......

上一篇: Ruby正則運算式 下一篇: Ruby多線程編程