套接字是網(wǎng)絡(luò)通信通道的端點,客戶端和服務(wù)器之間相互通信。它們可以在同一臺機器上或在不同的機器上進行通信。
套接字(Socket)的類型有以下幾種:
有兩個級別的套接字 - 高級和低級。 低級訪問允許您處理系統(tǒng)支持的套接字。 它允許實現(xiàn)無連接和面向連接的協(xié)議。 高級訪問允許您處理像HTTP和FTP這樣的網(wǎng)絡(luò)協(xié)議。
示例-1
創(chuàng)建一個服務(wù)器端 - 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
}
在上述代碼中,需要包括預(yù)先安裝的socket模塊。 在系統(tǒng)上使用8088端口。當然您可根據(jù)需要可以使用任何其它的端口。
啟動循環(huán),接受所有連接到8088端口,并通過套接字網(wǎng)絡(luò)將數(shù)據(jù)發(fā)送給客戶端。
最后,關(guān)閉套接字。
創(chuàng)建一個客戶端代碼 - 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
在上述代碼中,需要包括預(yù)先安裝的socket模塊。 創(chuàng)建一個套接字并將其連接到端口8088。
創(chuàng)建一個while循環(huán)來獲取通過套接字發(fā)送的所有信息。
最后,關(guān)閉套接字。
執(zhí)行輸出:
打開終端,轉(zhuǎn)到保存上述兩個文件的目錄,在本示例中,所有代碼均保存在:F:\worksp\ruby 目錄下。
現(xiàn)在打開兩個終端。在第一個終端先執(zhí)行服務(wù)器腳本(ruby server1.rb),服務(wù)器腳本啟動完成后,在第二個終端執(zhí)行以下命令執(zhí)行客戶端腳本,得到以下結(jié)果 -
F:\worksp\ruby>ruby client1.rb
Hello. This is socket programming
F:\worksp\ruby>
對于多個客戶端進行套接字編程,將需要一個循環(huán)和一些線程來接受和響應(yīng)多個客戶端連接和交互。
示例-2
創(chuàng)建一個服務(wù)器端 - 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" )
在上面的代碼中,服務(wù)器將與客戶端在指定的端口(8088)來建立連接。 在這里,每個連接的用戶需要一個線程來處理用戶連接信息交互。
run方法驗證輸入的名稱是否唯一。 如果用戶名已經(jīng)存在,連接將被斷開,否則將建立連接。
listen_user_messages方法用于偵聽用戶消息并將其發(fā)送給所有用戶。
創(chuàng)建一個客戶端代碼 - 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 )
在上面的代碼中,創(chuàng)建了Client類用來處理用戶。
在 send 和 listen 方法中創(chuàng)建兩個線程,以便可以同時讀取/寫入消息。
執(zhí)行輸出:
下面顯示兩個客戶端之間的聊天消息,首先執(zhí)行(ruby server2.rb),然后再運行兩個客戶端,在兩個客戶端之間發(fā)送信息聊天。

服務(wù)器(server2.rb)記錄每個客戶端連接信息 -
F:\worksp\ruby>ruby server2.rb
maxsu #<TCPSocket:0x00000002c3dc30>
minsu #<TCPSocket:0x00000002c3d730>
......