📜  Ruby套接字编程

📅  最后修改于: 2021-01-08 13:21:04             🧑  作者: Mango

Ruby套接字编程

套接字是网络通信通道的端点,客户端和服务器在此相互通信。他们可以在同一台计算机上或在不同的计算机上进行通信。

插座类型:

  • TCP套接字
  • UDP套接字
  • UNIX套接字

插座有两个级别,高和低。低级别访问权限使您可以在系统支持的套接字上工作。它允许同时实现无连接和面向连接的协议。高级访问权限使您可以处理HTTP和FTP等网络协议。

例1

server1.rb

#!/usr/bin/ruby 
require 'socket' 

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

在上面的代码中,需要包括预安装的套接字模块。我们正在系统上使用2017端口。您可以使用任何端口。

开始循环,接受到端口2017的所有连接,然后通过套接字网络将数据发送到客户端。

最后,关闭插座。

client1.rb

#!/usr/bin/ruby 
require 'socket' 

hostname = 'localhost' 
port = 2017 

s = TCPSocket.open(hostname, port) 

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

在上面的代码中,需要包括预安装的套接字模块。创建一个套接字并将其连接到端口2017。

创建一个while循环以获取通过套接字发送的所有信息。

最后,关闭插座。

输出:

转到终端,切换到以上两个文件已保存到的目录。我们已经将其保存在桌面目录中。

现在要执行这些文件,我们需要具有所需的权限。在终端中运行以下命令,

chmod a+x *.rb

该命令将使该目录中的所有Ruby文件都可执行。

现在打开两个终端。在第一终端中执行服务器脚本,在第二终端中执行以下命令。

ruby filename.rb

多客户端套接字编程

对于通过套接字编程的多个客户端,将需要一个循环和一些线程来接受和响应多个客户端。

例2

server3.rb

#!/usr/bin/env ruby -w 
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( 2019, "localhost" )

在上面的代码中,服务器将具有与客户端相同的端口以建立连接。这里,每个连接的用户需要一个线程来处理所有可能的用户。

运行方法验证输入的名称是否唯一。如果用户名已经存在,则连接将被终止,否则将建立连接。

listen_user_messages方法侦听用户消息并将其发送给所有用户。

client3.rb

#!/usr/bin/env ruby -w 
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", 2019 ) 
Client.new( server )

在上面的代码中,创建Client类来处理用户。

在sendlisten方法中创建了两个线程,以便我们可以同时读取/写入消息。

输出:

下面的快照显示了两个客户端之间的聊天。

服务器终端上的输出如下所示。