第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

使用 Ruby 進(jìn)行 Socket 編程

網(wǎng)絡(luò)是千萬(wàn)臺(tái)計(jì)算機(jī)通過(guò) TCP/IP 通信的結(jié)果??蛻舳苏?qǐng)求執(zhí)行某些操作,服務(wù)端執(zhí)行該操作并響應(yīng)客戶端,這種被我們成為請(qǐng)求-響應(yīng)模型。宏觀上來(lái)看,就是當(dāng)用戶通過(guò)瀏覽器瀏覽網(wǎng)站時(shí),請(qǐng)求發(fā)送到適當(dāng)?shù)?web 服務(wù)器,服務(wù)器通過(guò)發(fā)送適當(dāng)?shù)腍TML頁(yè)面來(lái)響應(yīng)客戶端。本章節(jié)主要帶大家了解一下 Ruby中如何進(jìn)行 Socket 應(yīng)用程序開(kāi)發(fā)。

1. 端口

在學(xué)習(xí)Socket編程之前我們要了解一下概念。

端口不是物理設(shè)備,而是促進(jìn)服務(wù)器和客戶端之間通信的抽象概念。

端口是由一個(gè) 2 的 16 次冪的整數(shù)表示的,所以,一臺(tái)機(jī)器最多可以有65536個(gè)端口(0~65535)。

端口一共分為三個(gè)種類:

  1. 知名端口:0 ~ 1023(例如:80端口用于http,25端口用于smtp)。
  2. 注冊(cè)端口:1024 ~ 49151。
  3. 動(dòng)態(tài)/私有端口:49152 ~ 65535。

2. IP地址

這里我們只說(shuō) IPV4,它是由 4 個(gè) 4 個(gè)字節(jié)數(shù)字組成的主機(jī)地址,比如:124.56.124.103。

127.0.0.1(localhost)代表了本地回送地址,它是一個(gè)特殊的地址,代表了本地計(jì)算機(jī)。

3. Socket

3.1 什么是 Socket

Socket 表示兩個(gè)網(wǎng)絡(luò)應(yīng)用程序之間的單個(gè)連接。這兩個(gè)應(yīng)用程序名義上可以在不同的計(jì)算機(jī)上運(yùn)行,并且Socket也可以在單臺(tái)計(jì)算機(jī)上實(shí)現(xiàn)進(jìn)程之間的通信。應(yīng)用程序可以創(chuàng)建多個(gè)用于相互通信的Socket。Socket 是雙向的,代表連接它的任何一方都可以發(fā)送和接收數(shù)據(jù)。

3.2 Ruby中Socket類

Ruby 中擁有非常豐富的 Socket 的類型。

圖片描述

上面是一張出自《Programming Ruby》的圖片,介紹了 Rub y中 Socket 的類型。

如上圖所示,所有的類都繼承了 IO 類。

下面的例子中我們會(huì)使用TCPSocket來(lái)進(jìn)行 Socket 的連接,使用TCPServer來(lái)創(chuàng)建一個(gè)TCP的服務(wù)器。

Tips:所有的Socket類都是標(biāo)準(zhǔn)庫(kù)的一部分(不是核心類的一部分),因此要使用require 'socket'才可以在程序中使用它。

下面的是服務(wù)端的代碼:

實(shí)例:

require 'socket'

server = TCPServer.new('127.0.0.1', 18000)
loop do
  Thread.start(server.accept) do |s|
    puts "#{s} is accepted."
    s.write(Time.now)
    puts "#{s} is gone."
    s.close
  end
end

解釋:

我們使用TCPServer在本地創(chuàng)建了一個(gè)TCP的Socket服務(wù)器serverThread.start創(chuàng)建了一個(gè)新的線程(線程詳細(xì)會(huì)在多線程章節(jié)中解釋)并執(zhí)行塊中的代碼指令。server.accept方法等待server上的鏈接,并返回鏈接到調(diào)用者的新TCPSocket對(duì)象s。loop do會(huì)一直迭代,直到退出循環(huán)。s.write會(huì)將時(shí)間寫(xiě)入到Socket之中。s.close會(huì)關(guān)閉socket。

這個(gè)腳本需要先啟動(dòng),剛啟動(dòng)時(shí)你不會(huì)看到任何輸出內(nèi)容。

下面是客戶端的代碼:

實(shí)例:

require 'socket'  

stream = TCPSocket.new('127.0.0.1', 18000)

string = stream.recv( 100 )  
puts string  
stream.close  

解釋:

我們使用TCPSocket.new('127.0.0.1', 18000)打開(kāi)了TCP連接。語(yǔ)句string = stream.recv( 100 )

定義我們從socket最多接收100個(gè)字節(jié)。然后打印從服務(wù)器端獲取到的時(shí)間,最后關(guān)閉socket。

服務(wù)端輸出內(nèi)容:

#<TCPSocket:0x00007fb54497d898> is accepted.
#<TCPSocket:0x00007fb54497d898> is gone.

客戶端輸出內(nèi)容:

2020-08-24 00:23:14 +0800

這是一個(gè)服務(wù)端發(fā)送,客戶端接收的例子。反過(guò)來(lái)依舊可以。

下面是服務(wù)端的代碼:

require 'socket'

server = TCPServer.new('127.0.0.1', 18000)
loop do
  Thread.start(server.accept) do |s|
    puts "#{s} is accepted."
    string = s.recv( 100 )  
    puts string
    puts "#{s} is gone."
    s.close
  end
end

下面是客戶端的代碼:

require 'socket'  

stream = TCPSocket.new('127.0.0.1', 18000)
stream.write(Time.now)

服務(wù)端輸出結(jié)果:

#<TCPSocket:0x00007fd6d714d1f0> is accepted.
2020-08-24 00:29:15 +0800
#<TCPSocket:0x00007fd6d714d1f0> is gone.

客戶端輸出結(jié)果:

# 無(wú)內(nèi)容

4. 小結(jié)

本節(jié)我們討論了 Socket 編程的基本類(例如Socket類),初步了解了 IP 以及端口號(hào),以及有助于簡(jiǎn)化 Ruby 中 Socket 編程的類,例如TCPSocketTCPServer,學(xué)習(xí)了使用 Socket 進(jìn)行交互的例子。