Ruby-socket-programming
Ruby-ソケットプログラミング
Rubyは、ネットワークサービスへの2つのレベルのアクセスを提供します。 低レベルでは、基盤となるオペレーティングシステムの基本的なソケットサポートにアクセスできます。これにより、接続指向プロトコルとコネクションレスプロトコルの両方のクライアントとサーバーを実装できます。
Rubyには、FTP、HTTPなど、特定のアプリケーションレベルのネットワークプロトコルへの高レベルのアクセスを提供するライブラリもあります。
この章では、ネットワーク-ソケットプログラミングの最も有名な概念を理解します。
ソケットとは何ですか?
ソケットは、双方向通信チャネルのエンドポイントです。 ソケットは、プロセス内、同じマシン上のプロセス間、または異なる大陸のプロセス間で通信できます。
ソケットは、Unixドメインソケット、TCP、UDPなど、さまざまなチャネルタイプで実装できます。 _socket_は、一般的なトランスポートを処理するための特定のクラスと、残りを処理するための汎用インターフェイスを提供します。
ソケットには独自の語彙があります-
Sr.No. | Term & Description |
---|---|
1 |
domain トランスポートメカニズムとして使用されるプロトコルファミリ。 これらの値は、PF_INET、PF_UNIX、PF_X25などの定数です。 |
2 |
type 2つのエンドポイント間の通信のタイプ。通常、接続指向プロトコルの場合はSOCK_STREAM、コネクションレスプロトコルの場合はSOCK_DGRAM。 |
3 |
protocol 通常、これはドメインおよびタイプ内のプロトコルのバリアントを識別するために使用できます。 |
4 |
hostname ネットワークインターフェイスの識別子- 文字列。ホスト名、ドット区切りのアドレス、またはコロン(および場合によってはドット)表記のIPV6アドレスを指定できます INADDR_BROADCASTアドレスを指定する文字列「<broadcast>」。 INADDR_ANYを指定する長さゼロの文字列、または ホストバイト順のバイナリアドレスとして解釈される整数。 |
5 |
port 各サーバーは、1つ以上のポートで呼び出しているクライアントをリッスンします。 ポートは、Fixnumポート番号、ポート番号を含む文字列、またはサービスの名前です。 |
シンプルなクライアント
ここでは、特定のポートとホストへの接続を開く非常に単純なクライアントプログラムを作成します。 Rubyクラス TCPSocket は、そのようなソケットを開く_open_関数を提供します。
- TCPSocket.open(hosname、port)*は、_port_上の_hostname_へのTCP接続を開きます。
ソケットを開いたら、IOオブジェクトのようにソケットから読み取ることができます。 完了したら、ファイルを閉じるのと同じように忘れずに閉じてください。
次のコードは、特定のホストとポートに接続し、ソケットから利用可能なデータを読み取り、終了する非常に単純なクライアントです-
require 'socket' # Sockets are in standard library
hostname = 'localhost'
port = 2000
s = TCPSocket.open(hostname, port)
while line = s.gets # Read lines from the socket
puts line.chop # And print with platform line terminator
end
s.close # Close the socket when done
シンプルなサーバー
インターネットサーバーを作成するには、 TCPServer クラスを使用します。 TCPServerオブジェクトは、TCPSocketオブジェクトのファクトリです。
*TCPServer.open(hostname、port* 関数を呼び出して、サービスの_port_を指定し、 *TCPServer* オブジェクトを作成します。
次に、返されたTCPServerオブジェクトの_accept_メソッドを呼び出します。 このメソッドは、クライアントが指定したポートに接続するまで待機し、そのクライアントへの接続を表す_TCPSocket_オブジェクトを返します。
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
client = server.accept # Wait for a client to connect
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
}
次に、このサーバーをバックグラウンドで実行してから、上記のクライアントを実行して結果を確認します。
マルチクライアントTCPサーバー
インターネット上のほとんどのサーバーは、一度に多数のクライアントを処理するように設計されています。
Rubyの_Thread_クラスは、メインプログラムがより多くの接続を待つことを許可しながら、要求を受け入れ、すぐに接続を処理するための新しい実行スレッドを作成するマルチスレッドサーバーを簡単に作成できます-
require 'socket' # Get sockets from stdlib
server = TCPServer.open(2000) # Socket to listen on port 2000
loop { # Servers run forever
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
client.close # Disconnect from the client
end
}
この例では、永続的なループがあり、server.acceptが応答すると、新しいスレッドが作成され、すぐに開始されて、スレッドに渡された接続オブジェクトを使用して、受け入れられた接続を処理します。 ただし、メインプログラムはすぐにループバックし、新しい接続を待機します。
この方法でRubyスレッドを使用するということは、コードが移植可能であり、Linux、OS X、およびWindows上で同じ方法で実行されることを意味します。
小さなWebブラウザー
ソケットライブラリを使用して、任意のインターネットプロトコルを実装できます。 ここに、例えば、ウェブページのコンテンツを取得するコードがあります-
require 'socket'
host = 'www.finddevguides.com' # The web server
port = 80 # Default HTTP port
path = "/index" # The file we want
# This is the HTTP request we send to fetch a file
request = "GET #{path} HTTP/1.0\r\n\r\n"
socket = TCPSocket.open(host,port) # Connect to server
socket.print(request) # Send request
response = socket.read # Read complete response
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2)
print body # And display it
- 同様のWebクライアントを実装するには、 *Net
- HTTP* などのビルド済みライブラリを使用してHTTPを操作できます。 これは、前のコードと同等のコードです-
require 'net/http' # The library we need
host = 'www.finddevguides.com' # The web server
path = '/index' # The file we want
http = Net::HTTP.new(host) # Create a connection
headers, body = http.get(path) # Request the file
if headers.code == "200" # Check the status code
print body
else
puts "#{headers.code} #{headers.message}"
end
FTP、SMTP、POP、およびIMAPプロトコルで動作する同様のライブラリを確認してください。
さらに読む
ソケットプログラミングのクイックスタートを提供しました。 これは大きなテーマであるため、詳細については、https://www.ruby-doc.org/stdlib/libdoc/socket/rdoc/indexl [Rubyソケットライブラリとクラスメソッド]を参照することをお勧めします。