Ruby でHTTP通信をする方法はいくつかあります。 最も簡単なのは、open-uriを使う方法でしょう。 単純にあるURIに対してGETリクエストを送り、返されたHTMLを表示するだけなら、以下のように1行で済ませることもできます。
$ ruby -ropen-uri -e 'open(ARGV[0]){|f| puts f.read }' http://www.klab.jp/
しかし簡単な分、open-uriではPOSTができなかったり、制約もあります。そういうときは net/http を使うといいです。
require 'uri'
require 'net/http'

Net::HTTP.version_1_2

uri=URI(ARGV[0])

Net::HTTP.start(uri.host, uri.port){|http|
  puts http.get(uri.path).body
}
で、上と同じことが実現できます。 open-uri や net/http はライブラリでHTTPのレイヤーまで実装してくれているため、プログラマはそれを呼び出すだけでHTTPによる通信をすることができます。 しかし上のようなプログラムを書いただけでは、わかるのはあくまで「ライブラリの使い方」であって、今回の「HTTPやソケットについて勉強したい」という目的を果たしたとは言えません。 というわけで、もう少し低いレイヤーの部分から実装してみます。 ソケット通信をしたい場合、Rubyには 'socket' というそのままの名前のライブラリがあるので、それを使います。 その中にある TCPSocket というクラスを使い、その上でHTTPの処理を実装してみます。 以下のようになります。
require 'uri'
require 'socket'

uri = URI(ARGV[0])

socket = TCPSocket.new(uri.host, uri.port)
socket.puts "GET / HTTP/1.0\r\n"
socket.puts "Host: #{uri.host}\r\n"
socket.puts "\r\n"

puts socket.read.split("\r\n\r\n")[1..-1].join("\r\n\r\n")

socket.close
ソケット通信といっても非常に簡単です。
socket = TCPSocket.new(uri.host, uri.port)
で開いたソケットに対して、
socket.print "GET / HTTP/1.0\r\n"
socket.print "Host: #{uri.host}\r\n"
socket.print "\r\n"
でGETリクエストを送ります。 HTTPのヘッダの行末文字はCRLFであるとRFCで定められているので、各行末に "\r\n" をつけています。 サーバ側ではCRを無視してLFを行末として解釈することが推奨されているので、実際には "\r" をつけなくてもきちんとレスポンスが返ってくる場合がほとんどだと思いますが、予期しない不具合に悩まされる可能性もあるので、規定には従っておいたほうが無難です。 上の3行目で空行を入れ、ヘッダフィールドの終わりを示しています。GETリクエストはヘッダフィールドのみなのでこれで終わりですが、POSTリクエストの場合はこのあとに body-part として、対象に送るパラメータを記述します。 さて、上記のコードはTCPSocketを使ってソケット通信を開始し、その上でHTTPによる通信処理を実装しました。 今度はTCPSocketがやっているソケットの生成部分についても自分で実装・・・と、やろうとしたところで、すでに takada-at が実装してしまっていました。(^^; というわけで、次は takada-at がその実装について解説します。