Ruby_09_SMTP邮件_Socket编程

Ruby_09_SMTP邮件_Socket编程_第1张图片

Ruby_09_SMTP邮件_Socket编程_第2张图片


Ruby 发送邮件 - SMATP

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址目的地址传送邮件的规则,由它来控制信件的中转方式。

Ruby提供了 Net::SMTP 来发送邮件,并提供了两个方法 new 和 start:

  • new 方法有两个参数:
    • server name 默认为 localhost
    • port number 默认为 25
  • start 方法有以下参数:
    • server - SMTP 服务器 IP, 默认为 localhost
    • port - 端口号,默认为 25
    • domain - 邮件发送者域名,默认为 ENV["HOSTNAME"]
    • account - 用户名,默认为 nil
    • password - 用户密码,默认为nil
    • authtype - 验证类型,默认为 cram_md5,补充一下:cram_md5即是一种Keyed-MD5验证方式,CRAM是“Challenge-Response Authentication Mechanism”的所写。所谓Keyed-MD5,是将Clieng与Server共享的一个Key作为一部分MD5的输入,正好邮件系统的用户口令可以作为这个Key。

成功或错误的状态码如下所示:

 ‘*************************  
  ‘*   邮件服务返回代码含义  
  ‘*   500   格式错误,命令不可识别(此错误也包括命令行过长)  
  ‘*   501   参数格式错误  
  ‘*   502   命令不可实现  
  ‘*   503   错误的命令序列  
  ‘*   504   命令参数不可实现  
  ‘*   211   系统状态或系统帮助响应  
  ‘*   214   帮助信息  
  ‘*   220     服务就绪  
  ‘*   221     服务关闭传输信道  
  ‘*   421     服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)  
  ‘*   250   要求的邮件操作完成  OK
  ‘*   251   用户非本地,将转发向  
  ‘*   450   要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)  
  ‘*   550   要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)  
  ‘*   451   放弃要求的操作;处理过程中出错  
  ‘*   551   用户非本地,请尝试  
  ‘*   452   系统存储不足,要求的操作未执行  
  ‘*   552   过量的存储分配,要求的操作未执行  
  ‘*   553   邮箱名不可用,要求的操作未执行(例如邮箱格式错误)  
  ‘*   354   开始邮件输入,以.结束  
  ‘*   554   操作失败  
  ‘*   535   用户验证失败  
  ‘*   235   用户验证成功  
  ‘*   334   等待用户输入验证信息


SMTP 对象实例化方法调用了 sendmail, 参数如下:

  • source - 一个字符串或数组或每个迭代器在任一时间中返回的任何东西。
  • sender -一个字符串,出现在 email 的表单字段。
  • recipients - 一个字符串或字符串数组,表示收件人的地址。

实例

以下提供了简单的Ruby脚本来发送非SSL的邮件(sina的是非SSL,QQ的是SSL):

首先打开新浪邮箱,进入设置,开启SMTP服务,如图所示:

Ruby_09_SMTP邮件_Socket编程_第3张图片

代码如下:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/smtp"
message = <
To: beyond <***@qq.com>
Subject: 这是邮件Subject

这是邮件正文,#{Time.now}
MESSAGE_END

Net::SMTP.start('smtp.sina.cn',25,'localhost',
	'username','password', :plain) do |smtp|
		smtp.send_message message,'***@sina.cn','***@qq.com'
end

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第4张图片

打开邮件后的效果:

Ruby_09_SMTP邮件_Socket编程_第5张图片

在以上实例中,你已经设置了一个基本的电子邮件消息,以及正确的标题格式。

一个电子邮件要要From,To和Subject,

注意: 邮件头部 与 邮件正文之间需要一个空行

使用Net::SMTP连接到本地机器上的SMTP服务器,

使用send_message方法来发送邮件,

方法参数为发送者邮箱 与 接收者邮

如果你没有运行在本机上的SMTP服务器,您可以使用Net::SMTP与远程SMTP服务器进行通信。

如果使用网络邮件服务(如新浪或QQ邮件),您的电子邮件提供者会为您提供发送邮件服务器的详细信息:

Net::SMTP.start('smtp.sina.cn')

以上代码将连接主机为 mail.sina.cn,端口号为 25的邮件服务器,

如果需要填写用户名密码,则代码如下:

Net::SMTP.start('smtp.sina.cn', 
                25, 
                'localhost', 
                'username', 'password', :plain)

以上实例使用了指定的用户名密码连接到主机为 mail.sina.cn,端口号为 25的邮件服务器。


使用 Ruby 发送 HTML 邮件

Net::SMTP同样提供了支持发送 HTML 格式的邮件。

发送电子邮件时你可以设置MIME版本,文档类型,字符集来发送HTML格式的邮件。

实例

以下实例用于发送 HTML 格式的邮件:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/smtp"

message = <
To: beyond <***@qq.com>
MIME-Version: 1.0
Content-type: text/html
Subject: 这是HTML邮件Subject

这是HMTL邮件正文,#{Time.now}

hello beyond

Copyright © 2018 Powered by beyond MESSAGE_BLOCK Net::SMTP.start('smtp.sina.cn',25,'localhost', 'username','passsword', :plain) do |smtp| puts smtp.send_message(message,'***@sina.cn','***@qq.com').message end

运行效果如下:


Ruby_09_SMTP邮件_Socket编程_第6张图片

Ruby_09_SMTP邮件_Socket编程_第7张图片


发送带附件的邮件(???发送成功,但是却收不到邮件???)

如果需要发送混合内容的电子邮件,需要设置Content-type为multipart/mixed。 

这样就可以在邮件中添加附件内容。

附件在传输前需要使用 pack("m") 函数将其内容转为 base64 格式。

实例

以下实例将发送附件为 /Users/beyond/sg_ruby/anime.txt 的邮件:

其中,anime.txt内容如下:

Ruby_09_SMTP邮件_Socket编程_第8张图片

代码如下:(注意格式千万不要写错,血的教训)

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'net/smtp'
require 'base64'

filenPath = "/Users/beyond/sg_ruby/anime.txt"
filename = "anime.txt"
#读取文件并编码成base64格式
fileContent = File.read(filenPath)
fileContent_encode = [fileContent].pack("m")


#定义分割线
separateLine = "THIS_IS_SEPARATE_LINE"

#定义头部信息
part1_head =<
To: <***@qq.com>
Subject: 使用SMTP发送带附件的邮件Subject
MIME-Version: 1.0
Content-Type: multipart/mixd; boundary=\"#{separateLine}\";charset=UTF-8
Content-Transfer-Encoding: 7bit


--#{separateLine}
HEAD_BLOCK

#定义body部分
body =< e
	print "发送失败:",e
end

注意:你可以指定多个发送的目的地址,但需要使用逗号隔开。


打印结果如下:

Last login: Sat Mar  3 00:46:45 on ttys003
bogon:~ beyond$ ruby /Users/beyond/sg_ruby/ruby_132.rb
From: <***@sina.cn>
To: <***@qq.com>
Subject: 使用SMTP发送带附件的邮件Subject
MIME-Version: 1.0
Content-Type: multipart/mixd; boundary="THIS_IS_SEPARATE_LINE";charset=UTF-8
Content-Transfer-Encoding: 7bit


--THIS_IS_SEPARATE_LINE
Content-Type: text/plain;charset=UTF-8
Content-Transfer-Encoding: base64

5oiR5Lus5LuN5pyq55+l6YGT6YKj5bm05aSP5aSp5omA55yL6KeB55qE6Iqx
55qE5ZCN5a2XCg==


--THIS_IS_SEPARATE_LINE
Content-Type: text/plain; filename=anime.txt;charset=UTF-8
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=anime.txt

5Zyo5oiR5Lus6LWw6L+H55qE5a2j6IqC6YeM77yMCui3r+aXgeebm+W8gOea
hOiKseacteS5n+WcqOS4jeaWreWPmOWMlu+8jArpgqPkuKrlraPoioLnm5vl
vIDnmoToirHmmK/lj6vku4DkuYjmnaXnnYDvvJ8K6L276L275pGH5puz552A
77yM5LiA56Kw5Lya5b6u5b6u5Yi655eb77yMCumdoOi/keS4gOmXu++8jOma
kOe6puacieiCoemdkua2qeeahOmYs+WFieeahOawlOaBr+OAggrpgqPmsJTm
ga/muJDmuJDlnLDmt6HljrvvvIzmiJHku6zkuZ/lnKjmhaLmhaLplb/lpKfj
gIIK5Y+v5piv77yM6YKj5py16Iqx5LiA5a6a6L+Y5Zyo5p+Q5Liq5Zyw5pa5
55ub5byA552A4oCm4oCmCuWvue+8jOaIkeS7rOawuOi/nOmDveS8mue7p+e7
reWunueOsOmCo+acteiKseeahOaEv+acm+OAggrigJTigJTigJTigJTigJTi
gJTigJTigJQ85pyq6Ze76Iqx5ZCNPg==

--THIS_IS_SEPARATE_LINE--
250 ok queue id 52545997012
bogon:~ beyond$ 

邮件效果如下:

Ruby_09_SMTP邮件_Socket编程_第9张图片



Ruby_09_SMTP邮件_Socket编程_第10张图片

附件预览如下:

Ruby_09_SMTP邮件_Socket编程_第11张图片




其他发送邮件附件的方法: 

使用mail进行发送邮件

1.先安装mail

sudo gem install mail

Ruby_09_SMTP邮件_Socket编程_第12张图片

然后代码如下:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "mail"

smtp = {:address => 'smtp.sina.cn',
		:pot => 25,
		:domain => "sina.cn",
		:user_name => "***@sina.cn",
		:password => "***",
		:enable_starttls_auto => true,
		:openssl_verify_mode => "none"}
Mail.defaults{delivery_method :smtp,smtp}
mail = Mail.new do 
	from "***@sina.cn"
	to "***@qq.com"
	subject "邮件使用mail发送"
	body "我们仍未知道那年夏天所看见的花的名字"
	add_file File.expand_path("/Users/beyond/sg_ruby/anime.txt")
	# add_file File.expand_path("/Users/beyond/sg_ruby/anohana.jpg")
end
puts mail.deliver!

运行效果如下:

Last login: Sat Mar  3 00:16:48 on ttys001
bogon:~ beyond$ ruby /Users/beyond/sg_ruby/ruby_133.rb
Non US-ASCII detected and no charset defined.
Defaulting to UTF-8, set your own if this is incorrect.
Date: Sat, 03 Mar 2018 00:24:32 +0800
From: ***@sina.cn
To: ***@qq.com
Message-ID: <[email protected]>
Subject: =?UTF-8?Q?=E9=82=AE=E4=BB=B6=E4=BD=BF=E7=94=A8mail=E5=8F=91=E9=80=81?=
Mime-Version: 1.0
Content-Type: multipart/mixed;
 boundary="--==_mimepart_5a997abf3765d_9d923fd48245244c39716";
 charset=UTF-8
Content-Transfer-Encoding: 7bit


----==_mimepart_5a997abf3765d_9d923fd48245244c39716
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: base64

5oiR5Lus5LuN5pyq55+l6YGT6YKj5bm05aSP5aSp5omA55yL6KeB55qE6Iqx
55qE5ZCN5a2X

----==_mimepart_5a997abf3765d_9d923fd48245244c39716
Content-Type: text/plain;
 charset=UTF-8;
 filename=anime.txt
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename=anime.txt
Content-ID: <[email protected]>

在我们走过的季节里,
路旁盛开的花朵也在不断变化,
那个季节盛开的花是叫什么来着?
轻轻摇曳着,一碰会微微刺痛,
靠近一闻,隐约有股青涩的阳光的气息。
那气息渐渐地淡去,我们也在慢慢长大。
可是,那朵花一定还在某个地方盛开着……
对,我们永远都会继续实现那朵花的愿望。
————————<未闻花名>
----==_mimepart_5a997abf3765d_9d923fd48245244c39716--
bogon:~ beyond$ 

收到的邮件如下:

Ruby_09_SMTP邮件_Socket编程_第13张图片


Ruby_09_SMTP邮件_Socket编程_第14张图片


预览附件如下:

Ruby_09_SMTP邮件_Socket编程_第15张图片


Ruby Socket 编程

Ruby提供了两个级别访问网络的服务,在底层你可以访问操作系统,它可以让你实现客户端和服务器为面向连接和无连接协议的基本套接字支持。

Ruby 统一支持应用程的网络协议,如FTP、HTTP等。

不管是高层的还是底层的。ruby提供了一些基本类,让你可以使用TCP,UDP,SOCKS等很多协议交互,而不必拘泥在网络层。这些类也提供了辅助类,让你可以轻松的对服务器进行读写。

接下来就让我们来学习如何进行 Ruby Socket 编程


什么是 Sockets

应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要 通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字 (Socket)的接口,区分不同应用程序进程间的网络通信和连接。

生成套接字,主要有3个参数:通信的目的IP地址、使用的传输 层协议(TCP或UDP)和使用的端口号。Socket原意是"插座"。通过将这3个参数结合起来,与一个"插座"Socket绑定,应用层就可以和传输 层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

Sockets 词汇解析:

选项 描述
domain 指明所使用的协议族,通常为 PF_INET, PF_UNIX, PF_X25, 等等。
type 指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议
protocol 通常赋值0。
hostname 网络接口的标识符:
  • 字符串, 可以是主机名或IP地址
  • 字符串 "", 指定 INADDR_BROADCAST 地址。
  • 0 长度的字符串, 指定INADDR_ANY
  • 一个整数,解释为主机字节顺序的二进制地址。
port port是端口的编号,每个服务器都会监听客户端连接的一个或多个端口号,一个端口号可以是 Fixnum 的端口号, 包含了服务器名和端口。

简单的客户端

以下我们通过给定的主机和端口编写了一个简单的客户端实例,Ruby TCPSocket 类提供了 open 方法来打开一个 socke。

TCPSocket.open(hosname, port ) 打开一个 TCP 连接。

一旦你打开一个 Socket 连接,你可以像 IO 对象一样读取它,完成后,你需要像关闭文件一样关闭该连接。

以下实例ruby_134.rb的代码演示了如何连接到一个指定的主机,并从 socket 中读取数据,最后关闭socket:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'socket'
hostname = 'localhost'
port = 5267
s = TCPSocket.open(hostname,port)
#阻塞循环等待读取内容
while line = s.gets
	#输入到终端
	puts line.chop
end
#最后记得关闭
s.close
现在还没有Server服务端,所以ruby_134.rb这个客户端请求到5267端口的时候悲剧了

Ruby_09_SMTP邮件_Socket编程_第16张图片

简单的服务

Ruby 中可以使用 TCPServer 类来写个简单的服务。

TCPServer 对象是 TCPSocket 的工厂对象。

现在我们使用 TCPServer.open(hostname, port) 来创建一个 TCPServer 对象。

接下来调用 TCPServer 的 accept 方法,该方法会等到一个客户端连接到指定的端口,然后返回一个的TCPSocket对象,表示连接到该客户端。

require 'socket'               # 获取socket标准库

server = TCPServer.open(5267)  # Socket 监听端口为 5267
loop {                         # 永久运行服务
  client = server.accept       # 等待客户端连接
  client.puts(Time.now.ctime)  # 发送时间到客户端
  client.puts "Closing the connection,farewell"
  client.close                 # 关闭客户端连接
}

 先运行ruby_135.rb这个server端,然后再运行上面写的ruby_134.rb这个客户端,效果如下:

Ruby_09_SMTP邮件_Socket编程_第17张图片


多客户端TCP服务

互联网上,大多服务都同时有大量的客户端连接。

Ruby的Thread类可以很容易地创建多线程服务,服务端的某一个子线程执行客户端的连接,而主线程则在等待更多的来自客户端的连接。

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'socket'
server = TCPServer.open(5267)
loop { 
	Thread.start(server.accept) do |client|
		client.puts("Hi client , I'am Server, welcome!")
		client.puts(Time.now)
		client.puts("Closing the connection,Farewell~")
		client.close
	end
}

在这个例子中,socket将会永久运行,而当server.accept接收到客户端的连接时,一个新的线程被创建并立即开始处理请求。

而主程序则立即循环回,并等待一个全新的来自客户端的连接。

Ruby_09_SMTP邮件_Socket编程_第18张图片


微小的Web浏览器

我们可以使用socket库来实现任何的 Internet 协议。

以下代码展示了如何获取网页的内容:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'socket'
host = 'localhost'
port = 80
path = "/index.html"
#连接服务器
socket = TCPSocket.open(host,port)
#指定请求头
requesHeader = "GET #{path} HTTP/1.0\r\n\r\n"
socket.print(requesHeader)
#读取结果
response = socket.read
#根据\r\n\r\n分割成返回头和返回的正文
headers,body = response.split("\r\n\r\n",2)
puts headers
puts ""
puts ""
puts body
Ruby_09_SMTP邮件_Socket编程_第19张图片


如果是想要实现一个类似 web 的客户端,你同样也可以使用为 HTTP 预先构建的库如Net::HTTP

以下代码与先前代码是等效的:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'net/http'
host = 'localhost'
filePath = '/index.html'

http = Net::HTTP.new(host,80)
response = http.get(filePath)

if response.code == "200" && response.message == "OK"
	puts response.body
else
	puts "#{response.code},#{response.message}"
end

如果文件存在,运行结果如下:

Ruby_09_SMTP邮件_Socket编程_第20张图片

如果文件不存在,报错信息如下:

Ruby_09_SMTP邮件_Socket编程_第21张图片


下面的代码也是一样的效果:

Ruby_09_SMTP邮件_Socket编程_第22张图片


您还可以把get到的网页源码写到文件中,ruby_138.rb的代码如下所示:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/http"
host = "localhost"
filePath = "/index.html"
port = "80"
http = Net::HTTP.new(host,port)

#写到文件
targetFilePath = "/Users/beyond/sg_ruby/httpSource_01.txt"
File.open(targetFilePath, "w") { |file|  
	http.get(filePath) do |response|
	file.write response		
	end
}

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第23张图片


您还可以通过URI.parse(urlStr)方法,ruby_139.rb代码如下:

Ruby_09_SMTP邮件_Socket编程_第24张图片


或者,您直接Net::HTTP.get_response(host,filePath)也可以,ruby_140.rb的代码如下:

Ruby_09_SMTP邮件_Socket编程_第25张图片

下面将演示如何抓取网页上的所有图片,网站的样子如下:

Ruby_09_SMTP邮件_Socket编程_第26张图片

打印输出该网页的源码,发现所有的高清图片的格式如下:

Ruby_09_SMTP邮件_Socket编程_第27张图片

故使用正则如下,ruby_141.rb的代码:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/http"

host = "www.xxx.com"
port = '80'
filePath = "/yyy/zzz.html"
http = Net::HTTP.new(host,port)
response = http.get(filePath)
puts response.body.scan(/"imgUrl":"(.*?)","name":/m).uniq

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第28张图片


您还可以使用open-uri抓取该页面的所有高清动漫图片,ruby_142.rb的代码如下:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

#能自动处理302
require 'open-uri'

urlStr = "http://xxx.com/yyy/zzz.html"
open(urlStr) do |f|
	puts f.read.scan(/"imgUrl":"(.*?)","name":/m).uniq
end

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第29张图片


您还可以使用ruby来发送带参数的POST请求,如下面代码所示:

ruby_143.rb是发送一个post请求:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'net/http'
#设定对象的运行方式
Net::HTTP.version_1_2
Net::HTTP.start('localhost',80) {|http|
	response = http.post("/cgi-bin/cgi_9.rb",
		"id=1&name=beyond")
	print response.code," ",response.message,"\n"
	puts response.body
}

而cgi_9.rb是一个CGI程序:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'cgi'

cgi = CGI.new("html4")
# 获取传递过来的POST参数
id = cgi['id']
name = cgi['name']
cgi.out{  
    cgi.html{  
        cgi.head{ "\n" +'' + cgi.title{"Ruby CGI"}}+  
        cgi.body{ "hello #{name},id is #{id}\n" 
        }  
    }  
}  

它收到ruby_143.rb发来的post请求中的参数id=1&name=beyond后,再输出一个html页面


注意,在运行CGI之前,先把权限设置一下 ,否则会报服务器内部500错误

sudo chmod 755 /Users/beyond/sg_python/cgi-bin/cgi_9.rb


Ruby_09_SMTP邮件_Socket编程_第30张图片


然后,就可以运行ruby_143.rb发送POST请求了

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第31张图片


关于open-uri简单说明一下用法:

像打开普通文件那样打开http/ftp的URL
open("http://www.baidu.com/") {|f|
  f.each_line {|line| p line}

}


打开的文件对象已经被OpenURI::Meta所扩展, 因此,您可以方便地获取meta信息。

require 'open-uri'

open("http://www.baidu.com") {|f|
  f.each_line {|line| p line}
  p f.base_uri         #
  p f.content_type     # "text/html"
  p f.charset          # "iso-8859-1"
  p f.content_encoding # []
  p f.last_modified    # Thu Dec 05 02:45:02 UTC 2002

}

代码如下:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'open-uri'
urlStr = "http://localhost"
open(urlStr){|f|
	f.each_line{|line|
		p line
	}
	p f.base_uri
	p f.content_type
	p f.charset
	p f.content_encoding
	p f.last_modified
}

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第32张图片



如果在参数中 使用哈希表参数,您还可以添加指定的头字段。

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require 'open-uri'
urlStr = "http://localhost"

open(urlStr,
  "User-Agent" => "Ruby/#{RUBY_VERSION}",
  "From" => "***@sina.cn",
  "Referer" => "http://www.baidu.com/") {|f|
  f.each_line {|line| p line}
}

运行效果如下:

Ruby_09_SMTP邮件_Socket编程_第33张图片


在默认情况下,http_proxy以及ftp_proxy这些环境变量都是有效的. 

若想禁用代理,可以这样 :proxy => nil 。

open("http://www.baidu.com/index.html",
  :proxy => nil) {|f|
  ...

}


URI对象的打开方式也是类似的。
uri = URI.parse("http://www.baidu.com/")
uri.open {|f|
  ...

}



您还可以直接读取URI对象。

返回的字符串已经被OpenURI::Meta所扩展。

str = uri.read

Ruby_09_SMTP邮件_Socket编程_第34张图片


另一种写法,其效果也是一样的:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/https"
require "uri"
urlStr = "http://localhost"
uri = URI.parse(urlStr)
http = Net::HTTP.new(uri.host,uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request.initialize_http_header("User-Agent" => "RUBY/#{RUBY_VERSION}")
response = http.request(request)
print response.code,",",response.message,",",response.body

Ruby_09_SMTP邮件_Socket编程_第35张图片


下面另外演示是一个POST请求的示例代码:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/https"
require "uri"
urlStr = "http://localhost/cgi-bin/cgi_9.rb"
uri = URI.parse(urlStr)
#发送post请求
response = Net::HTTP.post_form(uri,{"id" => "1",
							"name" => "beyond"})
puts response.body

Ruby_09_SMTP邮件_Socket编程_第36张图片


更加完整的一个Post请求:

#!/usr/bin/ruby 
# -*- coding: UTF-8 -*-
#coding=utf-8

require "net/https"
require "uri"
urlStr = "http://localhost/cgi-bin/cgi_9.rb"
uri = URI.parse(urlStr)
#更完整post请求
http = Net::HTTP.new(uri.host,uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({"id" => "1",
							"name" => "beyond"})
response = http.request(request)
puts response.body

Ruby_09_SMTP邮件_Socket编程_第37张图片


下面是带Cookie的POST请求示例代码片断:

# 带cookie的post请求
http = Net::HTTP.new(uri.host,uri.port)
filePath = "/login.html"
cookie = response["set-cookie"]
data = "key1=value1&key2=value2...."
headers = {"cookie"=>cookie,"content-type"=>"..."}
response = http.post(filePath,data,headers)
#或者:
request = NET::HTTP::Post.new(filePath)
request.set_form_data({"key1"=>"value1","key2"=>"value2"...."})
request.initialize_http_header({"cookie"=>cookie})
response = http.request(request)

下面是设置连接超时:

#设置请求的连接超时 时间
http = Net::HTTP.new(uri.host, uri.port)  
http.open_timeout = 5 # in seconds  
http.read_timeout = 5 # in seconds  

所有HTTP 1.0的请求方式列表如下:

# 所有的HTTP 1.1的请求method列表如下
Net::HTTP::Get  
Net::HTTP::Post  
Net::HTTP::Put  
Net::HTTP::Delete  
Net::HTTP::Head  
Net::HTTP::Options  


未完待续,下一章节,つづく



你可能感兴趣的:(Ruby)