郵件的協(xié)議及服務(wù)器工作原理
前言
相信大家在日常工作生活中少不了和郵件打交道,比如我們會用郵件進(jìn)行信息交流,向上級匯報日常工作;再比如大家熟悉的某個WEB系統(tǒng)注冊階段,通常會有一個功能,點擊發(fā)送到目標(biāo)郵箱的鏈接完成賬戶激活。
但是郵件發(fā)送的原理是什么?郵件是如何發(fā)送的呢?本系列教程將會講解郵件的基本常識與概念,郵件的協(xié)議以及郵件服務(wù)器的工作原理,然后用JavaMail發(fā)送郵件的基本實現(xiàn)過程,郵件內(nèi)嵌圖片等高級郵件技巧。相信大家看完后,一定會有所收獲。
電子郵件的發(fā)送和接收過程
和以往博客一樣,LZ這里先給出用戶A從QQ郵箱發(fā)送郵件到用戶B163郵箱的圖示,然后對圖示的過程進(jìn)行詳細(xì)的介紹:
圖示的六個步驟分別進(jìn)行如下的說明:
①、用戶A的電子郵箱為:xx@qq.com,通過郵件客戶端軟件寫好一封郵件,交到QQ的郵件服務(wù)器,這一步使用的協(xié)議是SMTP,對應(yīng)圖示的①;
②、QQ郵箱會根據(jù)用戶A發(fā)送的郵件進(jìn)行解析,也就是根據(jù)收件地址判斷是否是自己管轄的賬戶,如果收件地址也是QQ郵箱,那么會直接存放到自己的存儲空間。這里我們假設(shè)收件地址不是QQ郵箱,而是163郵箱,那么QQ郵箱就會將郵件轉(zhuǎn)發(fā)到163郵箱服務(wù)器,轉(zhuǎn)發(fā)使用的協(xié)議也是SMTP,對應(yīng)圖示的②;
③、163郵箱服務(wù)器接收到QQ郵箱轉(zhuǎn)發(fā)過來的郵件,也會判斷收件地址是否是自己,發(fā)現(xiàn)是自己的賬戶,那么就會將QQ郵箱轉(zhuǎn)發(fā)過來的郵件存放到自己的內(nèi)部存儲空間,對應(yīng)圖示的③;
④、用戶A將郵件發(fā)送了之后,就會通知用戶B去指定的郵箱收取郵件。用戶B會通過郵件客戶端軟件先向163郵箱服務(wù)器請求,要求收取自己的郵件,對應(yīng)圖示的④;
⑤、163郵箱服務(wù)器收到用戶B的請求后,會從自己的存儲空間中取出B未收取的郵件,對應(yīng)圖示⑤;
⑥、163郵箱服務(wù)器取出用戶B未收取的郵件后,將郵件發(fā)給用戶B,對應(yīng)圖示的⑥;最后三步用戶B收取郵件的過程,使用的協(xié)議是POP3;
上面的步驟可能大家不太明白,這里面出現(xiàn)了很多名詞,比如郵件客戶端軟件,郵件服務(wù)器,SMTP和POP3協(xié)議(郵件傳輸協(xié)議)等等。不明白沒關(guān)系,接下來我們來詳細(xì)介紹這些名詞。
1、郵件服務(wù)器
圖示出現(xiàn)了兩個郵件服務(wù)器,QQ和163郵件服務(wù)器。用戶想要在網(wǎng)上收發(fā)郵件,必須要有專門的郵件服務(wù)器。郵件服務(wù)器我們可以假想為現(xiàn)實生活中的郵局。
如果按功能劃分,郵件服務(wù)器可以劃分為兩種類型:
①、SMTP郵件服務(wù)器:用戶替用戶發(fā)送郵件和接收外面發(fā)送給本地用戶的郵件,對應(yīng)上圖的第一、二步。它相當(dāng)于現(xiàn)實生活中郵局的郵件接收部門(可接收普通用戶要投出的郵件和其他郵局投遞進(jìn)來的郵件)。
②、POP3/IMAP郵件服務(wù)器:用戶幫助用戶讀取SMTP郵件服務(wù)器接收進(jìn)來的郵件,對應(yīng)上圖的第六步。它相當(dāng)于專門為前來取包裹的用戶提供服務(wù)的部門。
2、電子郵箱
電子郵箱也稱為E-mail地址,比如用戶A的xx@qq.com,和用戶B的xx@163.com。用戶能通過E-mail地址標(biāo)識自己發(fā)送的電子郵件,同時也可以通過這個地址接收別人發(fā)來的電子郵件。電子郵箱需要到郵件服務(wù)器進(jìn)行申請,也就是說,電子郵箱其實就是用戶在郵件服務(wù)器上申請的賬戶。郵件服務(wù)器會把接收到的郵件保存到為該賬戶所分配的郵箱空間中,用戶通過用戶名密碼登錄到郵件服務(wù)器查收該地址已經(jīng)收到的郵件。一般來講,郵件服務(wù)器為用戶分配的郵箱空間是有限的。
3、郵件客戶端軟件
我們可以直接在網(wǎng)站上進(jìn)行郵件收發(fā),也可以用郵件客戶端軟件。比如常見的FoxMail,Outlook Express。郵件客戶端軟件通常集郵件撰寫,發(fā)送和收發(fā)功能于一體,主要用于幫助用戶將郵件發(fā)送給SMTP郵件服務(wù)器和從POP3/IMAP郵件服務(wù)器讀取用戶的電子郵件。
4、郵件傳輸協(xié)議
電子郵件需要在郵件客戶端和郵件服務(wù)器之間,以及兩個郵件服務(wù)器之間進(jìn)行郵件傳遞,那就必須要遵守一定的規(guī)則,這個規(guī)則就是郵件傳輸協(xié)議。下面我們分別簡單介紹幾種協(xié)議(后面會詳細(xì)講解):
①、SMTP協(xié)議:全稱為 Simple Mail Transfer Protocol,簡單郵件傳輸協(xié)議。它定義了郵件客戶端軟件和SMTP郵件服務(wù)器之間,以及兩臺SMTP郵件服務(wù)器之間的通信規(guī)則。
②、POP3協(xié)議:全稱為 Post Office Protocol,郵局協(xié)議。它定義了郵件客戶端軟件和POP3郵件服務(wù)器的通信規(guī)則。
③、IMAP協(xié)議:全稱為 Internet Message Access Protocol,Internet消息訪問協(xié)議,它是對POP3協(xié)議的一種擴展,也是定義了郵件客戶端軟件和IMAP郵件服務(wù)器的通信規(guī)則。
使用Smtp協(xié)議手工發(fā)送郵件
SMTP協(xié)議:全稱為 Simple Mail Transfer Protocol,簡單郵件傳輸協(xié)議。它定義了郵件客戶端軟件和SMTP郵件服務(wù)器之間,以及兩臺SMTP郵件服務(wù)器之間的通信規(guī)則。SMTP協(xié)議的通信雙方采用一問一答的命令/響應(yīng)形式進(jìn)行對話,SMTP協(xié)議分為標(biāo)準(zhǔn)SMTP協(xié)議和擴展SMTP協(xié)議,標(biāo)準(zhǔn)SMTP協(xié)議是1982年在RFC821 文檔中定義的,而擴展SMTP協(xié)議是1995年在RFC1869 文檔中定義的。擴展SMTP協(xié)議在標(biāo)準(zhǔn) SMTP協(xié)議基礎(chǔ)上的改動非常小,主要增加了郵件安全方面的認(rèn)證功能,現(xiàn)在我們說的SMTP協(xié)議基本上都是擴展SMTP協(xié)議。
RFC1869文檔參考如下:https://datatracker.ietf.org/doc/html/rfc1869
SMTP 協(xié)議中一共定義了18條命令,但是發(fā)送一封電子郵件的過程通常只需要6條命令,我將這6調(diào)命令/響應(yīng)的語法格式總結(jié)如下
大家可能光看這些命令不太清楚,下面我總結(jié)了一下使用Smtp協(xié)議手工發(fā)送郵件的步驟:
①、和SMTP服務(wù)器建立連接,telnet smtp.163.com 25。這條命令是和163郵箱建立連接,如果是和QQ,那么將163換成qq即可,同理別的郵箱也是一樣。后面的數(shù)字25表示SMTP服務(wù)器的端口號。
②、ehlo 發(fā)件人用戶名。這沒什么好說的,就是告訴SMTP服務(wù)器發(fā)送者的用戶名。
③、選擇登錄認(rèn)證方式,一般我們在第二步執(zhí)行完后,會提示有幾種認(rèn)證方式,我們一般選擇的是login。即輸入命令:auth login
④、分別輸入經(jīng)過Base64加密后的用戶名和密碼。注意必須是要經(jīng)過 Base64加密后的用戶名和密碼,大家可以網(wǎng)上在線轉(zhuǎn),也可以用后面給的代碼進(jìn)行轉(zhuǎn)換。
⑤、指明郵件的發(fā)送人和收件人
mail from:<xxx@163.com>
rcpt to:<xxx@qq.com>
⑥、輸入data命令,然后編寫要發(fā)送的郵件內(nèi)容,郵件的編寫格式規(guī)則如下:
第一步:輸入data
第二步:輸入郵件內(nèi)容
from:<xxx@163.com>----郵件頭發(fā)件人地址 to:<xxx@qq.com> ----郵件頭收件人地址 subject:hello world ----郵件頭主題 -----空行 This is the first email sent by hand using the SMTP protocol ----郵件的具體內(nèi)容
⑦、輸入“.”表示郵件內(nèi)容輸入完畢
⑧、輸入quit命令斷開與郵件服務(wù)器的連接
下面我用動圖的形式給大家展示用Smtp協(xié)議手工發(fā)送郵件的前面三個步驟:
上面我執(zhí)行到第4步,剩下的步驟我就直接截圖了:
至此,我們一封郵件便發(fā)出去了,我們先登陸到QQ郵箱查看(后面我們通過POP3服務(wù)器來查收):
SMTP發(fā)送郵件遇到問題
①、執(zhí)行 telent smtp.163.com 25 命令時,報如下錯誤:
解決辦法是:控制面板----程序------啟動或關(guān)閉 Windows 功能----將Telnet勾上,然后點擊確定即可
②、用戶名和密碼必須要base64加密,在線網(wǎng)站:http://www1.tc711.com/tool/BASE64.htm
③、每一步驟之間輸入命令要盡量快,不然會自動斷開連接
④、我上面是和163郵箱鏈接的,如果是和qq郵箱連接,會有一些問題。首先第一步建立連接為 telnet smtp.qq.com 587,端口號為587,不是25。還有第三步,選擇認(rèn)證方式,在執(zhí)行 auth login之前,先執(zhí)行:starttls。還有第四步,輸入用戶名和授權(quán)碼,而不是用戶名和密碼,授權(quán)碼的獲取可以參考:
什么是授權(quán)碼,它又是如何設(shè)置?_QQ郵箱幫助中心
⑤、輸入郵件內(nèi)容時,空行不要忘記了,還有結(jié)束輸入是以“.”結(jié)束的。
使用POP3協(xié)議手工接收郵件
郵件服務(wù)商專門為每個用戶申請的電子郵箱提供了專門的存儲空間,SMTP 服務(wù)器將接收到的郵件保存到相應(yīng)用戶的存儲空間。用戶要從郵件服務(wù)提供商提供的電子郵箱中獲取自己的電子郵件,那么就需要POP3 郵件服務(wù)器來完成。
POP3協(xié)議:全稱為 Post Office Protocol,它定義了郵件客戶端程序和POP3郵件服務(wù)器的通信規(guī)則。
下面我們演示用POP3協(xié)議手工接收郵件:
這是在 163 郵箱的一份郵件。(這里沒有用qq郵箱演示是因為qq有很多安全限制,步驟比較繁瑣,大家遇到問題了可以留言問我)
第一步:用telnet 連接POP3的163郵箱服務(wù)器
接下來收取郵件:
相關(guān)命令的詳細(xì)解釋如下:
RFC822 郵件格式
英文參考文檔如下:
https://datatracker.ietf.org/doc/html/rfc822
RFC822 文檔中定義的文件格式包括兩個部分:郵件頭和郵件體。在上一篇博客,我們通過SMTP服務(wù)發(fā)送一封郵件,然后用POP3服務(wù)器接收。郵件接收內(nèi)容如下圖紅色框所顯示:
這上面顯示的不全,我這里將其內(nèi)容整理出來,并在每行左邊加上標(biāo)號:
1 Received: from smtpbg5.qq.com (unknown [183.60.61.230]) by mx6 (Coremail) with SMTP id OMCowACXv+ssf99ZD5FqAg--.5570S3; Thu, 12 Oct 2017 22:41:48 +0800 (CST) 2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1507819308; bh=N2xK6iU/bt0tcntOdutSQ3tkYXbTtOi08RT+HjuXmBc=; h=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID; b=lzBtxAWw0+HB1bGLkkCqlUeU4bvVoMxDp3UZTKq3YCIJt5Ypu4FkE0m5rrrpcxF0D W0/PQajrQTughLTmpjoudI5aDWjfrfkOc1Z0+ltaAraoZfdE5HmNQ0hxQstNa+IbjC GMVEzCOMikVm5qklyCz/1Lwd5mBJ90YkknS3sL08= 3 X-QQ-FEAT: Gf8h89u9tNwRjwDYIPPhYegibbvTgUmwr4I/ntV6mwr6YOyFiWpUpVj+bCsJz tAz24NjMs/p1D8BXG7LYvZRCPMPQV7jdW3AKjTclrSS9xE29fxWsEjYk5QlD1cMIuhHF9Po 1HMwWKIZX8q6smehIwr+t/du8sprvHVue4ty5KMPeWw967qaAZgta5hcnRtgajhZRcIumVx r+K4/nY7I+wwNenOTfHT4Ly4K1Ne+vD7VNJbLHH674HEJ2CsoSEEBW7X/LeeSq6M= 4 X-QQ-SSF: 0001000000000010000000000000007 5 X-HAS-ATTACH: no 6 X-QQ-BUSINESS-ORIGIN: 2 7 X-Originating-IP: 113.57.253.69 8 X-QQ-STYLE: 9 X-QQ-mid: webmail4t1507819307t4823829 10 From: "=?ISO-8859-1?B?MTEzMjgwMzk1MQ==?=" <1132803951@qq.com> 11 To: "=?ISO-8859-1?B?MTgyNzEyNjU3MzI=?=" <18271265732@163.com> 12 Subject: hello world 13 Mime-Version: 1.0 14 Content-Type: multipart/alternative; boundary="----=_NextPart_59DF7F2B_08CB07D0_339F08F2" 15 Content-Transfer-Encoding: 8Bit 16 Date: Thu, 12 Oct 2017 22:41:47 +0800 17 X-Priority: 3 18 Message-ID: <tencent_9EFED46440A5BAD43E6BC680FAC8A58E460A@qq.com> 19 X-QQ-MIME: TCMime 1.0 by Tencent 20 X-Mailer: QQMail 2.x 21 X-QQ-Mailer: QQMail 2.x 22 X-QQ-SENDSIZE: 520 23 Received: from qq.com (unknown [10.137.130.92]) by smtp.qq.com (ESMTP) with SMTP id ; Thu, 12 Oct 2017 22:41:47 +0800 (CST) 24 Feedback-ID: webmail:qq.com:bgweb:bgweb4 25 X-CM-TRANSID:OMCowACXv+ssf99ZD5FqAg--.5570S3 26 Authentication-Results: mx6; spf=pass smtp.mail=1132803951@qq.com; dki m=pass header.i=@qq.com 27 X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73 VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvj4RWLvtDUUUU 28 This is a multi-part message in MIME format. 29 Content-Type: text/plain; charset="ISO-8859-1" 30 Content-Transfer-Encoding: base64 31 PGRpdj48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6ICdsdWNpZGEgR3JhbmRlJywgVmVyZGFu YSwgJ01pY3Jvc29mdCBZYUhlaSc7IGxpbmUtaGVpZ2h0OiAyMy44cHg7Ij5UaGlzIGlzIHRo ZSBmaXJzdCBlbWFpbCBzZW50IGJ5IGhhbmQgdXNpbmcgdGhlIFNNVFAgcHJvdG9jb2w8L3Nw YW4+PC9kaXY+
上面便是RFC822 所定義的郵件格式,從第 1 行到第 30 行都是郵件頭,第 31 行是郵件體(經(jīng)過base64加密過了,有興趣的大家可以解碼看看)。而郵件頭和郵件體之間以一個空行間隔,郵件頭部分是由多個頭字段和字段內(nèi)容組成,分別表示收件人,發(fā)件人,發(fā)件時間,主題等信息。還有一些信息是對應(yīng)的SMTP服務(wù)器在郵件傳遞過程中所加上的,我們知道現(xiàn)實生活中的郵局在處理郵件時,通常都會在信封上加上郵戳,表示這封郵件在什么時候經(jīng)過了哪個郵局哪個部門處理,我們上個例子是QQ郵箱發(fā)給163郵箱的。而SMTP服務(wù)器按從下往上的方式添加信息,即先添加的字段位于后添加字段的后面。所以qq的SMTP服務(wù)器會先添加頭字段,但是添加的字段會在163的SMTP服務(wù)器添加字段的下面,另外 POP3服務(wù)器也會自己添加一些字段。
每一個郵件頭以“字段名:字段值”的格式出現(xiàn),即每一行郵件頭的內(nèi)容依次由字段名、冒號、空格、字段值、回車換行符組成。RFC822文檔中定義了多個標(biāo)準(zhǔn)的郵件頭字段,每一個郵件頭字段表示一種特定的信息。郵件頭中也可以包含自定義的頭字段,這種自定義的頭字段通常是某個組織或機構(gòu)內(nèi)部專用的。下面是對一些主要的郵件頭字段的解釋:
我們從上可以知道,RFC822文檔存在兩個問題:
①、定義了郵件內(nèi)容的主體結(jié)構(gòu)和各種郵件頭字段的詳細(xì)細(xì)節(jié),但是,它沒有定義郵件體的格式,RFC822文檔定義的郵件體部分通常都只能用于表述一段普通的文本,而無法表達(dá)出圖片、聲音等二進(jìn)制數(shù)據(jù)。
②、SMTP服務(wù)器在接收郵件內(nèi)容時,當(dāng)接收到只有一個“.”字符的單獨行時,就會認(rèn)為郵件內(nèi)容已經(jīng)結(jié)束,如果一封郵件正文中正好有內(nèi)容僅為一個“.”字符的單獨行,SMTP服務(wù)器就會丟棄掉該行后面的內(nèi)容,從而導(dǎo)致信息丟失。
上面兩個問題是致命的,當(dāng)今的電子郵件,人們希望在電子郵件中嵌入圖片、聲音、動畫和附件。但是,由于圖片和聲音等內(nèi)容是非ASCII碼的二進(jìn)制數(shù)據(jù),而RFC822郵件格式只適合用來表達(dá)純文本的郵件內(nèi)容,所以,要使用RFC822郵件格式發(fā)送這些非ASCII碼的二進(jìn)制數(shù)據(jù)時,必須先采用某種編碼方式將它們“編碼”成可打印的ASCII字符后再作為RFC822郵件格式的內(nèi)容。郵件閱讀程序在讀取到這種經(jīng)過編碼處理的郵件后,再按照相應(yīng)的解碼方式解碼出原始的二進(jìn)制數(shù)據(jù),這樣就可以借助RFC822郵件格式來傳遞多媒體數(shù)據(jù)了。這種做法需要解決一下兩個技術(shù)問題:
一、郵件閱讀程序如何知道郵件中嵌入的原始二進(jìn)制數(shù)據(jù)所采用的編碼方式;
二、郵件閱讀程序如何知道每個嵌入的圖像或其他資源在整個郵件內(nèi)容中的起止位置。
為了解決上面兩個問題,人們后來專門為此定義了MIME(Multipurpose Internet Mail Extension,多用途Internet郵件擴展)協(xié)議。
MIME協(xié)議
MIME協(xié)議用于定義復(fù)雜郵件體的格式,它可以表達(dá)多段平行的文本內(nèi)容和非文本的郵件內(nèi)容,例如,在郵件體中內(nèi)嵌的圖像數(shù)據(jù)和郵件附件等。另外,MIME協(xié)議的數(shù)據(jù)格式也可以避免郵件內(nèi)容在傳輸過程中發(fā)生信息丟失。MIME協(xié)議不是對RFC822郵件格式的升級和替代,而是基于RFC822郵件格式的擴展應(yīng)用。一言以蔽之,RFC822定義了郵件內(nèi)容的格式和郵件頭字段的詳細(xì)細(xì)節(jié),MIME協(xié)議則是定義了如何在郵件體部分表達(dá)出的豐富多樣的數(shù)據(jù)內(nèi)容。
一個采用了MIME協(xié)議的電子郵件就叫做MIME郵件,MIME郵件在RFC822文檔中定義的郵件頭字段的基礎(chǔ)上,擴充了一些自己專用的郵件頭字段,例如,使用MIME-Version頭字段指定MIME協(xié)議的版本,使用Content-Type頭字段指定郵件體的MIME類型,使用Content-Transfer-Encoding頭字段指定編碼方法,如下所示:
MIME-Version:1.0 Content-Type:multipart/mixed;boundary="----=_NextPart_000_0050_01C"
其中,“multipart/mixed”部分說明郵件體中包含有多段數(shù)據(jù),每段數(shù)據(jù)之間使用boundary屬性中指定的字符文本作為分隔標(biāo)識符。另外,MIME郵件也擴展了RFC822文檔中已經(jīng)定義了的郵件頭字段的內(nèi)涵,例如,定義了subject頭字段中的值內(nèi)容的格式,以便通過編碼的方式讓郵件主題中也可以使用非ASCII碼的字符。subject頭字段中的值嵌套在一對“=?”和“?=”標(biāo)記符之間,標(biāo)記符之間的內(nèi)容由三部分組成:郵件主題的原始內(nèi)容的字符集、當(dāng)前采用的編碼方式、編碼后的結(jié)果,這三部分之間使用“?”進(jìn)行分隔。
以上就是郵件的協(xié)議及服務(wù)器工作原理的詳細(xì)內(nèi)容,更多關(guān)于郵件協(xié)議服務(wù)器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
快速解決eclipse中注釋的代碼依然會執(zhí)行的問題
下面小編就為大家?guī)硪黄焖俳鉀Qeclipse中注釋的代碼依然會執(zhí)行的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12用VSCode實現(xiàn)內(nèi)網(wǎng)穿透的步驟詳解
這篇文章給大家介紹了如何用VSCode實現(xiàn)內(nèi)網(wǎng)穿透,文中通過圖文結(jié)合的方式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12微信小程序 iPhoneX底部安全區(qū)域(底部小黑條)適配(一分鐘解決)
iPhone X 對于微信小程序的tabbar來說,會被底部小黑條覆蓋,需要處理,大概思路是,得到手機型號、分別判斷樣式。這篇文章主要介紹了微信小程序 iPhoneX底部安全區(qū)域(底部小黑條)適配問題,需要的朋友可以參考下2019-10-10gaussdb 200安裝 data studio jdbc idea鏈接保姆級安裝步驟
這篇文章主要介紹了gaussdb 200安裝 data studio jdbc idea鏈接保姆級安裝步驟,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08使用Postman和SoapUI工具測試WebService接口
這篇文章介紹了使用Postman和SoapUI工具測試WebService接口的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06VSCODE添加open with code實現(xiàn)右鍵打開文件夾
這篇文章主要介紹了VSCODE添加open with code實現(xiàn)右鍵打開文件夾,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05