精华内容
下载资源
问答
  • 处理邮件发送请求的协议是
    千次阅读
    2021-03-25 10:26:22

    电子邮件是一种异步通信媒介,即当人们方便时就可以收发邮件,不必与他人的计划进行协调。

    因特网的电子邮件系统有3个主要组成部分:用户代理(user agent)、邮件服务器(mail server)、简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)。

    SMTP

    SMTP是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持,SMTP的重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。使用SMTP,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。

    SMTP是一个”“的协议,是Internet电子邮件的核心。SMTP服务的默认端口为25。

    工作过程

    SMTP协议的工作过程可分为如下3个过程:

    (1)建立连接:在这一阶段,SMTP客户请求与服务器的25端口建立一个TCP连接。一旦连接建立,SMTP服务器和客户就开始相互通告自己的域名,同时确认对方的域名。

    (2)邮件传送:利用命令,SMTP客户将邮件的源地址、目的地址和邮件的具体内容传递给SMTP服务器,SMTP服务器进行相应的响应并接收邮件。

    (3)连接释放:SMTP客户发出退出命令,服务器在处理命令后进行响应,随后关闭TCP连接。

    功能

    SMTP是一组用于从源地址到目的地址传送邮件的规则,并且控制信件的中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,我们就可以把E—mail寄到收信人的服务器上了,整个过程只需要几分钟。SMTP服务器是遵循SMTP协议的发送邮件服务器,用来发送或中转用户发出的电子邮件。

    SMTP是一种提供可靠且有效电子邮件传输的协议。它是建立在FTP文件传输服务上的一种邮件服务,主要用于传输系统之间的邮件信息并提供来信有关的通知。

    SMTP重要的特性之一是它能跨越网络传输邮件,也即“SMTP邮件中继”。使用SMTP,可实现相同网络上处理机之间的邮件传输,也可以通过中继器或网关实现某处理机与其它网络之间的邮件传输。具有域名服务系统(DNS)功能的邮件交换服务器还可以用来识别出传输邮件的下一跳IP地址。

    应用范围

    在这里插入图片描述

    如上图所示,SMTP用来将邮件从发送方的邮件服务传输到接收方的邮件服务器;SMTP也可以将邮件从发送方的用户代理传送到发送方的邮件服务器。如POP3这样的邮件访问协议用来将邮件从接收方的邮件服务器传送到接收方的用户代理。

    POP3

    POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。是TCP/IP协议族中的一员,由RFC1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。提供了SSL加密的POP3协议被称为POP3S。

    POP 协议支持“离线”邮件处理。其具体过程是:邮件发送到服务器上,电子邮件客户端调用邮件客户机程序以连接服务器,并下载所有未阅读的电子邮件。这种离线访问模式是一种存储转发服务,将邮件从邮件服务器端送到个人终端机器上,一般是PC机或 MAC。一旦邮件发送到 PC 机或MAC上,邮件服务器上的邮件将会被删除。但POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的POP3协议。

    POP3协议默认端口为110,默认传输协议为TCP,使用的架构为C/S,访问模式为离线访问。

    使用POP3的用户代理通常被用户配置为”下载并删除“或者”下载并保留“方式。POP3用户代理发出的命令序列取决于用户代理程序被配置为这两种方式的哪一种。

    使用下载并删除的问题在于,如果在一台机器上收取了一条邮件,那么在其他机器上就不能再收取该邮件,而下载并保留则能够实现在不同机器上访问这些邮件。

    IMAP

    IMAP(Internet Mail Access Protocol)以前称作交互邮件访问协议(Interactive Mail Access Protocol),是一个应用层协议。IMAP是斯坦福大学在1986年开发的一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。当前的权威定义是RFC3501。IMAP协议运行在TCP/IP协议之上,使用的端口是143。它与POP3协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。

    POP3协议只能实现将邮件报文下载到本地建立本地文件夹,而IMAP则能够实现在远程服务器上建立文件夹存储邮件报文。

    IMAP的另一重要特性是允许用户代理获取报文某些部分的命令。当用户代理和其邮件服务器之间使用低带宽连接时,这一特性尤为重要。使用低带宽连接时,用户可能不想取回他邮箱中的所有邮件,尤其要避免可能包含如音频或视频片段的大邮件。

    基于Web的电子邮件

    使用这种服务,用户代理就是浏览器,则用户和他远程邮件服务器之间的通信是通过HTTP进行的,当一个人通过浏览器访问他邮箱中的一个报文时,该邮件报文是通过HTTP从接收方的邮件服务器发送到他的浏览器上的,但是邮件服务器之间的传输仍然使用SMTP。

    更多相关内容
  • 电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件。...也就是说SMTP的命令是要组合在一起才能完成一次邮件发送任务,单独调用每个命令的意义不大。POP3命令则不同,LIST、STAT、UIDL、TOP、RETR、

    电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件。SMTP的全称为Simple Mail Transfer Protocol,也就是简单邮件传输协议,字如其名。
     
    相较于POP3而言,SMTP确实比较简单。这里的简单并不是指SMTP的命令比POP3少,而是指SMTP的命令是有序的,而POP3的命令是无序的,理解这一点很重要。也就是说SMTP的命令是要组合在一起才能完成一次邮件发送任务,单独调用每个命令的意义不大。POP3命令则不同,LIST、STAT、UIDL、TOP、RETR、DELE等命令都可以独立使用,比如用LIST命令查看邮件清单,然后用RETR命令接收邮件。
     
    简单的另一层含义是:就socket编程而言实现发送数据要比实现接收数据简单点。
    比如接收数据时要判断数据是否接收完毕。如果一条数据以回车换行结束,就需要判断是否接收到了"\r\n",从而确保读取到一条完整的消息体。而发送数据则不需要考虑上述问题,你可以按照自己的节奏发送数据,可以一次将整个消息体发送出去,也可以不用考虑服务器的死活一个字节一个字节发送数据,直至将整条消息发送完毕。
    换句话说,接收数据要以流的方式进行,而不是简单的开辟一个缓冲区,进行一次recv操作。 虽然大部分情况下这种方式也没有问题,比如写个Demo程序,但如果要让你的网络程序非常健壮的话,最好以流的方式进行读取。因为并不是每次对方都会按照你期望的方式发送数据给你,比如,你开辟了1024字节缓冲区用于接收网络数据,但对方可能一次只给你发送一个字节,或者发出了1025个字节。
     
    SMTP和HTTP协议一样都属于请求应答式协议,也就是一问一答,客户端发送命令后,服务器返回响应内容。 SMTP的响应格式和HTTP协议的基本一样,都是响应码+响应描述。响应码用三位数字表示,空格后则是响应信息的描述,只是HTTP协议会多一个版本信息。

    这种一问一答式协议,在HTTP协议上体现的并不是很明显,只有HTTP连接设置为Keep-Alive时,你才有机会使用GET或POST命令反复与服务器进行交互,否则只有一次问答的机会。

    但在SMTP协议下这种一问一答的交互方式就非常明显了。 主要原因是完成一次邮件的发送任务涉及到的步骤比较多,我把电子邮件的发送分为如下五个步骤:

    1、建立会话;
    2、身份认证;
    3、发送邮件信封(发件人和收件人);
    4、发送邮件内容(邮件正文和附件);
    5、关闭会话

    在这里插入图片描述
    SMTP的命令主要就分布在这五个步骤中。下面以网易的yeah邮箱(smtp.yeah.net服务器)为例,具体说明这五个步骤的实现。C代表客户端,S代表服务端
     

    一、建立会话

    SMTP命令:HELO
    该阶段用于建立客户端与SMTP服务器的连接,在此基础上,双方进行友好的问候。SMTP服务器的默认端口号是25,如果是支持SSL协议,则默认端口号是465。如果采用的是STARTTLS协议,则默认端口是587,所谓的STARTSSL其实就是SSL协议,只是开始会话前双方客套一下,问一下对方你还支持SSL啊?

    连接建立后,服务器会发送一条欢迎语。接着你就需要问候一下服务器,并带上你的机器的名称。如下:

    S: 220 yeah.net Anti-spam GT for Coremail System (yeah[20141016])
    C: HELO your-computer-name
    S: 250 OK
    

     

    二、身份认证

    SMTP命令:AUTH LOGIN
    该命令用于进行身份验证,虽然这一步在SMTP协议中不是强制的要求,但目前几乎所有的SMTP服务器都需要进行身份认证。增加这一步可以大大减少垃圾邮件的存在,以及避免有人伪造其它发件人进行邮件的发送操作。
    这一步中账号和密码需要进行base64编码,包括服务器发来的提示信息也是base64编码。
    首先发送AUTH LOGIN命令,服务器会返回“334 XNlcm5hbWU6”,“dXNlcm5hbWU6”解码后为“username:”
    UGFzc3dvcmQ6解码为"Password:"
    也就是提示用户输入用户名和密码。认证成功后返回235注意返回的不是二百五(250)哦。 接着根据服务器返回的提示,发送账号(发件人的邮箱账号)和密码。

    C: AUTH LOGIN
    S: 334 dXNlcm5hbWU6
    C: base64编码后的账号(发件人的邮箱账号)
    S: 334 UGFzc3dvcmQ6
    C: base64编码后的密码
    S: 235 Authentication successful
    

    至于为何是base64编码,可能是SMTP协议设计时考虑到用户名和密码的重要性,所采用的最简单的“加密”手段。虽然base64只是编码方式,不是加密方式,但在早期控制台输入命令的情况下,别人还是一下无法像记住明文一样记住这些无规律的base64编码。不过随着SSL的应用,这些都已不重要了。
     

    三、发送邮件信封

    SMTP命令:MAIL FROM、RCPT TO
    该阶段是告诉服务器发件人和收件人的邮箱地址,可以把这个阶段想象为你在写纸质信件的信封。MAIL FROM用于指定发件人邮箱,该邮箱地址其实就是上述身份认证中的账号,如:
    MAIL FROM: <lig4961@yeah.net>
    RCPT TO用于指定收件人邮箱,一次只能指定一个收件人地址,如果收件人有多个的话,可以多次发送RCPT TO命令。

    C: MAIL FROM: <lig4961@yeah.net>
    S: 250 Mail OK
    C: RCPT TO: <syfzxm@163.com>
    S: 250 Mail OK
    C: RCPT TO: <lig4961@yeah.net>
    S: 250 Mail OK
    

    注意,邮件地址要用放入<>中,此外,每条命令发送完毕后,一定要判断服务器返回码是否是250。 如果返回的不是二百五,说明你发送的地址可能是二百五,也就是不正确的地址,比如邮件地址中没有@,或者在同一个邮箱系统中,SMTP服务器发现收件人的地址并不存在,也就是没有注册过。

    看到这里可能有人会有疑问:我们通过邮件客户端或网页写邮件时,不是有三种身份的收件人么?即:主送人(to)、抄送人(cc)、密送人(bcc)。是否存在RCPT CC和RCPT BCC命令,用于发送抄送人和密送人的邮箱地址呢?很遗憾,没有这两个命令。也就是说抄送人(cc)和密送人(bcc),也是通过RCPT TO命令进行发送。
     
    既然发送时不区分,那么我们在收到的邮件中怎么还能看到主送人和抄送人呢?或者说如何做到让密送人在收到的邮件中看不见的。答案在下面邮件内容中。
     

    四、发送邮件内容

    SMTP命令:DATA

    这一步是发送数据最多也是最复杂的一步,但操作命令却只有一个,就是DATA,也就是数据(邮件内容),邮件内容主要包括三个部分(可能会有内嵌资源文件,也可以理解为狭义上的附件):

    1、邮件头;
    2、邮件正文;
    3、邮件附件;

    DATA命令发送后,服务器会返回354响应码,并告诉客户端,数据结束要以"\r\n.\r\n"来标识。接下来客户端就可以发送整个邮件内容了。

    DATA
    354 End data with <CR><LF>.<CR><LF>
    SUBJECT: =?UTF-8?B?5p2l6IeqU29mdGxlZe+8jOi/meaYr+S4gOWwgea1i+ivlemCruS7tg==?=
    FROM: <lig4961@yeah.net>
    TO: 'softlee1' <syfzxm@163.com>, 'softlee2' <lig4961@yeah.net>
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
            boundary="=NextPart_SOFTLEE_Mail_E0B1A829CB1D4f55A037AE04B6A72078"
    
    --=NextPart_SOFTLEE_Mail_E0B1A829CB1D4f55A037AE04B6A72078
    Content-Type: text/html; charset=utf-8
    Content-Transfer-Encoding: base64
    
    PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgVHJhbnNpdGlvbmFs
    Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL3hodG1sMS9EVEQveGh0bWwxLXRyYW5zaXRpb25h
    bC5kdGQiPg0KPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPg0KDQo8
    aGVhZD4NCiAgICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQv
    

    邮件内容的格式目前基本都采用MIME格式,MIME格式比较简单,可参见文章:《如何解析EML(邮件)格式的文件以及一款小巧的EML邮件阅读工具》。
     
    这里我们不具体介绍如何编码邮件正文和附件。主要介绍邮件头中的信息,主题(Subject)、发件人(From)、收件人(To)、抄送(Cc)。我们看查看邮件时,读到的主题、收件人和抄送人就来自于上述字段。这里收件人和抄送人仅作为邮件头的一部分进行展现,服务器并不会关心这些地址是否真实存在,或者说服务器并不关心这些地址是否跟使用RCPT TO命令发送的地址保持一致。回到第三阶段中最后的几个问题,我们可以通过邮件头来展现该邮件的抄送人是谁,并且将密送人隐藏掉。当然你也可以篡改上述信息,比如隐瞒某些收件人,或者将密送人也一并展现。
     
    邮件正文和附件的编码可参照MIME格式的文章。最后所有数据发送完毕后,一定要发送"\r\n.\r\n",从而告诉SMTP服务器所有数据发送完毕。
     

    五、会话结束

    SMTP命令:QUIT
    这一步非常简单,就是发送一条QUIT命令,QUIT命令发送完毕后,还是要判断服务器的返回码是否为250。如果返回的不是,则表明发送失败,SMTP服务器可能不会将邮件转发到收件人所在的邮箱中,这一点很重要。

    至此,整个SMTP协议介绍完毕。SMTP协议比较简单,但具体的实现细节可能还有很多,需要在实践中去体验,有的服务器返回消息体是多行的,比如outlook邮箱的服务器,下面是outlook邮箱使用STARTTLS协议截图:
     
    在这里插入图片描述
     

    附一: SMTP邮件发送工具
    该工具特点:
    1、基于命令行方式且只有一个独立文件;
    2、支持SSL、STARTSSL协议;
    3、具有丰富的命令行参数;

    附二: 电子邮件相关文章和工具
    POP3协议(电子邮件邮局协议)中UIDL和TOP命令在实际使用中的作用
    POP3:基于命令行的电子邮件(EMail)在线查看和批量下载工具
    EmlParse:一款超轻量级的批量解析EML格式电子邮件的工具

    展开全文
  • HTTP协议请求

    千次阅读 2021-12-12 15:18:27
    也就是说,先从客户端开始建立通信的,服务端在没有接受到请求之前不会发送响应。且HTTP协议自身不对请求和响应之间的通信状态进行保存。 (在进行下一步学习之前首先要了解一下HTTP的消息结构) HTTP消息结构 ...

    什么是HTTP协议请求?

    HTTP协议规定,请求从客户端发出,最后服务端响应该请求并返回。也就是说,先从客户端开始建立通信的,服务端在没有接受到请求之前不会发送响应。且HTTP协议自身不对请求和响应之间的通信状态进行保存。

    (在进行下一步学习之前首先要了解一下HTTP的消息结构)

    HTTP消息结构

    HTTP是基于客户端/服务端的构架模型,通过一个可靠的链接在交换消息,是一个无状态的请求/响应协议。

    一个HTTP“客户端”是一个应用程序,通过连接到服务器达到向服务器发送一个HTTP或多个HTTP的请求的目的。

    一个HTTP“服务器”同样也是一个应用程序,通过接收客户端的请求并向客户端发送HTTP响应数据。

    HTTP使用统一资源标识符来传输数据和建立连接。一旦建立连接后,数据消息就通过类似Internet邮件所使用的格式和多用途Internet邮件扩展来传送。

    客户端请求消息

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行、请求头部、空行、请求数据

    请求报文的一般格式如下图所示:

    img

    服务器响应消息

    HTTP响应也由四个部分组成:状态行、消息报头、空行、响应正文

    img

    HTTP协议的8种请求类型

    OPTIONS:

    返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送请求来测试服务器的功能性。允许客户端查看服务器性能。

    HEAD:

    向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回,这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的源信息。(类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头。)

    GET:

    向特定的资源发出请求。即请求指定的页面信息,并返回实体主体。

    POST:

    向指定资源提交数据进行处理请求(eg:提交表单上或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建或已有资源的修改。

    PUT:

    向指定资源位置上传其最新内容。(从客户端向服务器传送的数据取代指定的文档的内容)

    DELETE:

    请求服务器删除Request-URI所标识的资源。(请求服务器删除指定的页面)

    TRACE:

    回显服务器收到的请求,主要用于测试或诊断。

    CONNECT:

    HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    注:管道方式:在等待上一个响应的同时,发送下一个请求。

    (虽然HTTP的请求方式有8种,但是实际应用种常用的是GET和POST,其他请求方式都可以通过这两种方式间接来实现。)

    HTTP响应头信息

    HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。

    应答头主要有:

    Allow:服务器支持哪些请求方法(如GET、POST等)。

    Content Encoding:文档的编码方法。只有在解码之后才可以得到Content-Type头指定的内容类型。用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。

    Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。

    Content-Type:表示后面的文档属于什么MIME类型。

    Date:当前的GMT时间。(可以使用setDateHeader来设置这个头避免转换时间格式的麻烦)

    Expires:应该在什么时候认为文档过期,从而不再缓存它。

    Last-Modified:文档最后改动的时间。

    Location:表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。

    Refresh:表示浏览器应该在多久之后刷新文档,以秒计。除了刷新当前文档之外,还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。

    注:连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新。

    Server:服务器名字(Servlet一般不设置这个值,而是由Web服务器自己设置)

    Set-Cookie:设置和页面关联的Cookie。

    WWW-Authenticate:客户应该在Authentication头中提供什么类型的授权信息?在包含401状态行的应答中这个头是必需的。

    注:Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问。

    HTTP状态码

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在的服务器发送请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头用以响应浏览器的请求。

    常见的HTTP状态码

    200-请求成功

    301-资源(网页等)被永久转移到其他URL。(什么时URL:即统一资源定位符,它用来表示互联网的某个资源地址,互联网上的每个文件都有唯一的URL,它包含信息指出文件的位置以及浏览器应该怎么处理它。)

    404-请求的资源(网页等)不存在。

    500-内部服务器错误。

    GET和POST的区别(前面提到最常用的两种请求方式是GET和POST,下面对其进行比较)

    我们常说的一些区别都是一些表面上的,比如:GET没有POST安全、GET请求时URL的长度是有限制的、GET没有bodyPOSTbody等等。这些都是针对浏览器中的要求, 在使用HTTP作为接口进行传输时,就没有这么多条条框框了,此时GETPOST只是HTTP协议中的两种请求方式,而HTTP协议是基于TCP/IP应用层协议, 无论GET还是POST,用的都是同一个传输层协议,所以在传输上没有区别。

    因此,在用作为接口进行传输时,最大的不同就在于报文格式上的不同了

    POST /url HTTP/1.1 \r\n GET /url HTTP/1.1 \r\n

    上面所示的分别为POST方法请求的报文第一行和GET请求的报文第一行, 显而易见的区别就是方法名不同。除此以外,就没有那么多要求了,GET也可以有bodyPOST也不一定非要使用body,只要客户端和服务器端确定好规范即可,至于形式则你们随意。只不过现在已经习惯了现有的规则,再去改变有些麻烦,毕竟客户端和服务器端要花时间去探讨具体的对接形式。

    由于平时大部分见到的都是基于浏览器的请求,下面我们再看几个常见的问题

    1. 我们前面说,无论是GET请求还是POST请求,其本质都是不安全的,为什么这样说呢?如果仅仅从GET请求的参数在地址栏是可见的,POST是不可见的,那就太肤浅了。 由于HTTP自己本身是一个明文协议,每个HTTP请求和返回的数据在网络上都是明文传播,无论是urlheader还是body。 只要在网络节点捉包,就能获取完整的数据报文,要防止泄密的唯一手段就是使用HTTPS(用SSL协议协商出的密钥加密明文HTTP数据)。

    2. 为什么在浏览器中GET请求方式的url长度有限制呢?这是因为浏览器要对url进行解析,而解析的时候就要分配内存。对于一个字节流的解析,必须分配buffer来保存所有要存储的数据。而url这种东西必须当作一个整体看待,无法一块一块处理,于是就处理一个请求时必须分配一整块足够大的内存。如果url太长,而并发又很高,就容易挤爆服务器的内存。

    3. POST是发送两个请求吗? 上面提到POST请求可以被分为“请求头”和“请求体”两个部分,那这两部分是一起发送出去呢?还是先发“请求头”,再发“请求体”呢? 在HTTP协议中并没有明确说明POST会产生两个数据包。之所以会发两个数据包,则是出于以下考虑:如果服务器先收到“请求头”,则会对其进行校验,如果校验通过,则回复客户端“100 - Continue”,客户端再把”请求体“发给服务器。如果请求被拒了,服务器就回复个400之类的错误,这个交互就终止了。这样做的优点是可以避免浪费带宽传输请求体,但是代价就是会多一次Round Trip。如果刚好请求体的数据也不多,那么一次性全部发给服务器可能反而更好。所以说,这和POST完全没有关系,只是基于两端的一种优化手段罢了。

    展开全文
  • SMTP 协议邮件发送工具封装

    千次阅读 2019-08-07 18:16:38
    文章目录1. 前言1.1 说明1.2 建议1.3 源码2. 发件人邮箱开通smtp 服务2.1 为什么要开通smtp 服务2.2 开启服务的步骤2.3 普通... 模拟邮件发送接口及接口测试 1. 前言 1.1 说明     此处为Jav...


    内个, 祝各位七夕快乐 ^ _ ^

    1. 前言

    1.1 说明

        此处为Java 版,封装了邮件发送工具,支持smtp 服务的邮箱,对发件人邮箱要求开通smtp 服务,否则不会发送邮件。
        发件邮箱发件过多时,可能会被收件邮箱作为恶意发件人,之后再接收该发件人的邮件会作为垃圾邮件。

    1.2 建议

        生产环境配置多发件人使用轮询机制发送。
        收件人标记发件人不是垃圾邮件。

    1.3 源码

        https://github.com/niaonao/email

    2. 发件人邮箱开通smtp 服务

    2.1 为什么开通smtp 服务

        点击链接可以看下原理
        简单的说,邮件可以通过smtp 协议在各个邮件服务器之间传输。

    2.2 开启服务的步骤

    • 开启smtp服务;
    • 获取授权码/密码;

        此授权码用于第三方邮件客户端登录时作为账号密码验证账号登录。
        授权码可以重置。

        /**
         * 邮件发送者账户
         * 邮件发送协议 smtp 账号密码/账号授权码
         */
        private static final String emailSenderAccount = "2171128382@qq.com";
        private static final String emailSenderAuthCode = "ojaerigbrwgmdjed";
    

    2.3 普通邮箱开启服务图文

    (1)腾讯邮箱
    在这里插入图片描述

    图2-1.腾讯邮箱开启SMTP 服务图

    在这里插入图片描述

    图2-2.请求获取授权码图

    在这里插入图片描述

    图2-3.获取授权码图

    (2)网易邮箱
    在这里插入图片描述

    图2-4.网易邮箱开启SMTP 服务图

    在这里插入图片描述

    图2-5.网易邮箱设置授权码图

    3. 工具类封装

    3.1 邮件依赖管理

    <!-- 邮件: https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
    

    3.2 日志依赖管理

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    

    3.3 邮件工具类封装

    package pers.niaonao.email.util;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.CollectionUtils;
    import pers.niaonao.email.constant.SystemConstant;
    
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.mail.internet.MimeUtility;
    import java.io.UnsupportedEncodingException;
    import java.util.Date;
    import java.util.List;
    import java.util.Properties;
    
    /**
     * @className: SMTPEmailUtil
     * @description: 邮件工具类
     *
     *      推荐文章更好理解smtp原理: <<手工体验smtp和pop3协议>> https://www.cnblogs.com/ysocean/p/7653252.html
     *
     *      SMTP 协议发送邮件
     *      (1) 获取会话 Session, 配置环境信息及用户授权验证
     *      (2) 创建邮件 Message, 完善邮件对象消息`主题`附件`日期`发送者接收者抄送者密送者等信息
     *      (3) 发送邮件 Transport, 提供网络传输对象发送邮件
     *
     *      邮件交互会话 javax.mail.Session: Session 对象保存了邮件系统的配置信息及提供用户验证
     *      密码验证类 Authenticator, 是抽象类, 可以新建实现类去覆盖原方法, 也可以像下面静态代码块直接使用.
     *      编写邮件需要 MimeMessage 对象, 该对象是抽象类的 javax.mail.Message 的一个实现类;
     *
     * @author: niaonao
     * @date: 2019/7/24
     **/
    @Slf4j
    public class SMTPEmailUtil {
    
        /**
         * 邮件发送者账户
         * 邮件发送协议 smtp 账号密码/账号授权码
         * 发件人
         * (邮件发送者从业务上看应支持系统配置, 此处就直接写好了数据; 你可以维护在配置文件,系统参数或数据库)
         */
        private static final String emailSenderAccount = "2171128382@qq.com";
        private static final String emailSenderAuthCode = "ojaerigbrwgmdjed";
        private static final String emailSenderName = "哪都通物流有限公司";
    
        /**
         * 环境信息
         */
        private static Properties props = new Properties();
    
        static {
            // 设置用户的认证方式, 邮箱账户, 授权码
            props.put(SystemConstant.MAIL_SMTP_HOST, getHost(emailSenderAccount));
            props.setProperty(SystemConstant.MAIL_SMTP_AUTH, String.valueOf(Boolean.TRUE));
            props.put(SystemConstant.MAIL_SMTP_USER, emailSenderAccount);
            props.put(SystemConstant.MAIL_SMTP_PASSWORD, emailSenderAuthCode);
        }
    
        /**
         * @description: 邮箱服务器域名通用转换, 格式支持多数邮件服务器, 部分不支持
         * @param email
         * @return: java.lang.String
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static String getHost(String email) {
            return new StringBuffer(SystemConstant.SMTP)
                    .append(SystemConstant.SYMBOL_POINT)
                    .append(email.split(SystemConstant.SYMBOL_AT)[1])
                    .toString();
        }
    
        /**
         * @description: 获取共享的 Session
         * @return: javax.mail.Session
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static Session getSession() {
            return Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(emailSenderAccount, emailSenderAuthCode);
                }
            });
        }
    
        /**
         * @description: 获取非共享的Session, 方法内部使用了 synchronized 关键字
         * lambda的使用条件是‘a functional interface has exactly one abstract method’
         * abstract class 使用lambda 的话要改造满足该条件
         * @return: javax.mail.Session
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static Session getDefaultInstance() {
            return Session.getDefaultInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(emailSenderAccount, emailSenderAuthCode);
                }
            });
        }
    
        /**
         * @description: 默认邮件发送者
         *      即配置邮箱和密码\授权码的账户
         * @param
         * @return: javax.mail.internet.InternetAddress
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static InternetAddress getDefaultSender() {
            try {
                return new InternetAddress(emailSenderAccount, emailSenderName, SystemConstant.CHARSET_UTF_8);
            } catch (UnsupportedEncodingException e) {
                log.error("[邮件工具]: 初始化异常{}", e.getMessage());
                throw new RuntimeException("获取默认邮件发送人错误!");
            }
        }
    
        /**
         * @description: 传输工具
         * @return: javax.mail.Transport
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static Transport getTransport() throws MessagingException {
            // 设置邮件协议 smtp
            Transport transport = getSession().getTransport(SystemConstant.SMTP);
            // 此处 QQ 邮箱, 通过账号和授权码链接
            transport.connect(getHost(emailSenderAccount), emailSenderAccount, emailSenderAuthCode);
            return transport;
        }
    
    
        /**
         * @description: 收件人转换 Address 对象
         * @param receiverEmailList
         * @return: javax.mail.internet.InternetAddress[]
         * @author: niaonao
         * @date: 2019/7/25
         */
        private static InternetAddress[] tranAddressByList(List<String> receiverEmailList) {
            /*List<InternetAddress> internetAddressList = new ArrayList<>();
            receiverEmailList.forEach(item -> {
                InternetAddress internetAddress = new InternetAddress();
                internetAddress.setAddress(item);
                internetAddressList.add(internetAddress);
            });
            InternetAddress[] addresses = internetAddressList.stream().toArray(InternetAddress[]::new);*/
    
            if (CollectionUtils.isEmpty(receiverEmailList)) {
                return null;
            }
    
            InternetAddress[] address = new InternetAddress[receiverEmailList.size()];
            for (int index = 0; index < receiverEmailList.size(); index++) {
                InternetAddress internetAddress = new InternetAddress();
                internetAddress.setAddress(receiverEmailList.get(index));
                address[index] = internetAddress;
            }
            return address;
        }
    
        /**
         * @description: 发送普通文本
         * @param subject 邮件主题
         * @param text  邮件普通文本内容
         * @param emailReceiverAccount  接收者
         * @param sendDate  邮件发送时间
         * @return: void
         * @author: niaonao
         * @date: 2019/7/24
         */
        public static void sendEmailByText(String subject, String text, String emailReceiverAccount, Date sendDate) {
            try {
                // 邮件对象
                MimeMessage msg = new MimeMessage(getSession());
                // 发送人
                msg.setFrom(getDefaultSender());
                // 发送方式,接收人
                msg.setRecipients(Message.RecipientType.TO, emailReceiverAccount);
                // 消息
                msg.setSubject(subject);
                msg.setText(text);
                if (null != sendDate) {
                    msg.setSentDate(sendDate.before(new Date()) ? new Date() : sendDate);
                } else {
                    // 邮件默认立即发送
                    msg.setSentDate(new Date());
                }
                //发送邮件
                Transport.send(msg);
                log.info("[邮件发送]: 邮件已发送!");
            } catch (MessagingException e) {
                log.error("[邮件发送]: 普通文本邮件发送异常, {}", e.getMessage());
            }
        }
    
        /**
         * @description: 发送普通消息邮件(多收件人)
         * @param subject   邮件标题
         * @param text      邮件内容
         * @param receiverEmailList 接收人
         * @param sendDate  邮件发送时间
         * @return: void
         * @author: niaonao
         * @date: 2019/7/25
         */
        public static void sendEmailByText(String subject, String text, List<String> receiverEmailList, Date sendDate) {
            InternetAddress[] addresses = tranAddressByList(receiverEmailList);
            try {
                // 邮件对象
                MimeMessage msg = new MimeMessage(getSession());
                msg.setFrom(getDefaultSender());
                msg.setRecipients(Message.RecipientType.TO, addresses);
                msg.setSubject(subject);
                msg.setText(text);
                if (null != sendDate) {
                    msg.setSentDate(sendDate.before(new Date()) ? new Date() : sendDate);
                }
                // 开启传输,发送邮件
                Transport transport = getTransport();
                transport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
                // 关闭链接
                transport.close();
                log.info("[邮件发送]: 邮件已发送!");
            } catch (MessagingException e) {
                log.error("[邮件发送]: 普通文本邮件发送异常, {}", e.getMessage());
            }
        }
    
        /**
         * @description: 发送普通文本消息(指定接收人,抄送人,密送人)
         * @param subject   邮件主题
         * @param text      邮件内容
         * @param receiverEmailList 邮件接收人
         * @param carbonCopyList    邮件抄送人
         * @param blindCarbonCopyList   邮件密送人
         * @param sendDate  邮件发送时间
         * @return: void
         * @author: niaonao
         * @date: 2019/7/25
         */
        public static void sendEmailByText(String subject, String text, List<String> receiverEmailList, List<String> carbonCopyList, List<String> blindCarbonCopyList, Date sendDate) {
            InternetAddress[] receiverAddresses = tranAddressByList(receiverEmailList);
            InternetAddress[] carbonCopyAddresses = tranAddressByList(carbonCopyList);
            InternetAddress[] blindCarbonCopyAddresses = tranAddressByList(blindCarbonCopyList);
            try {
                // 邮件对象
                MimeMessage msg = new MimeMessage(getSession());
                msg.setFrom(getDefaultSender());
                // 发送方式,接收人
                msg.setRecipients(Message.RecipientType.TO, receiverAddresses);
                msg.setRecipients(Message.RecipientType.CC, carbonCopyAddresses);
                msg.setRecipients(Message.RecipientType.BCC, blindCarbonCopyAddresses);
                // 消息
                msg.setSubject(subject);
                msg.setText(text);
                if (null != sendDate) {
                    msg.setSentDate(sendDate.before(new Date()) ? new Date() : sendDate);
                }
                // 开启传输,发送邮件
                Transport transport = getTransport();
                transport.sendMessage(msg, msg.getAllRecipients());
                // 关闭链接
                transport.close();
                log.info("[邮件发送]: 邮件已发送!");
            } catch (MessagingException e) {
                log.error("[邮件发送]: 普通文本邮件发送异常, {}", e.getMessage());
            }
        }
    
        /**
         * @description: 发送网页HTML 格式内容
         * @param subject   邮件标题
         * @param html      邮件内容, 语法HTML
         * @param receiverEmailList
         * @param carbonCopyList
         * @param blindCarbonCopyList
         * @param sendDate
         * @return: void
         * @author: niaonao
         * @date: 2019/7/25
         */
        public static void sendEmailByHtml(String subject, String html, List<String> receiverEmailList, List<String> carbonCopyList, List<String> blindCarbonCopyList, Date sendDate) {
            InternetAddress[] receiverAddresses = tranAddressByList(receiverEmailList);
            InternetAddress[] carbonCopyAddresses = tranAddressByList(carbonCopyList);
            InternetAddress[] blindCarbonCopyaddresses = tranAddressByList(blindCarbonCopyList);
            try {
                MimeMessage mimeMessage = new MimeMessage(getSession());
    
                // 发送方式,接收人
                mimeMessage.setRecipients(Message.RecipientType.TO, receiverAddresses);
                mimeMessage.setRecipients(Message.RecipientType.CC, carbonCopyAddresses);
                mimeMessage.setRecipients(Message.RecipientType.BCC, blindCarbonCopyaddresses);
    
                mimeMessage.setFrom(getDefaultSender());
                mimeMessage.setSubject(subject);
                mimeMessage.setContent(html, SystemConstant.CHARSET_TYPE_HTML);
                if (null != sendDate) {
                    mimeMessage.setSentDate(sendDate.before(new Date()) ? new Date() : sendDate);
                }
    
                Transport transport = getTransport();
                transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
                transport.close();
                log.info("[邮件发送]: HTML 网页邮件已发送!");
            } catch (MessagingException e) {
                log.error("[邮件发送]: HTML 网页邮件发送异常, {}", e.getMessage());
                e.printStackTrace();
            }
        }
    
    
        /**
         * @description: 发送携带附件的邮件
         * @param subject   邮件标题
         * @param html      邮件内容, 语法HTML
         * @param receiverEmailList
         * @param carbonCopyList
         * @param blindCarbonCopyList
         * @param sendDate
         * @return: void
         * @author: niaonao
         * @date: 2019/7/25
         */
        public static void sendEmailByEnclosure(String subject, String html, List<String> fileUrlList, List<String> receiverEmailList, List<String> carbonCopyList, List<String> blindCarbonCopyList, Date sendDate) {
            InternetAddress[] receiverAddresses = tranAddressByList(receiverEmailList);
            InternetAddress[] carbonCopyAddresses = tranAddressByList(carbonCopyList);
            InternetAddress[] blindCarbonCopyaddresses = tranAddressByList(blindCarbonCopyList);
            try {
                // html 节点
                MimeBodyPart contentPart = new MimeBodyPart();
                contentPart.setContent(html, SystemConstant.CHARSET_TYPE_HTML);
    
                // 组合节点
                MimeMultipart multipart = new MimeMultipart();
                for (String url:fileUrlList) {
                    // 附件节点
                    MimeBodyPart enclosure = new MimeBodyPart();
                    // 读取文件
                    // 将附件数据添加到"节点"
                    DataHandler dataHandler = new DataHandler(new FileDataSource(url));
                    enclosure.setDataHandler(dataHandler);
                    enclosure.setFileName(MimeUtility.encodeText(dataHandler.getName()));
                    multipart.addBodyPart(enclosure);
                }
                multipart.addBodyPart(contentPart);
                multipart.setSubType(SystemConstant.SUB_TYPE_MIXED);
    
                // 邮件对象
                MimeMessage mimeMessage = new MimeMessage(getSession());
                mimeMessage.setRecipients(Message.RecipientType.TO, receiverAddresses);
                mimeMessage.setRecipients(Message.RecipientType.CC, carbonCopyAddresses);
                mimeMessage.setRecipients(Message.RecipientType.BCC, blindCarbonCopyaddresses);
                mimeMessage.setFrom(getDefaultSender());
                mimeMessage.setSubject(subject);
                mimeMessage.setContent(multipart);
                if (null != sendDate) {
                    mimeMessage.setSentDate(sendDate.before(new Date()) ? new Date() : sendDate);
                }
    
                Transport transport = getTransport();
                transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
                transport.close();
                log.info("[邮件发送]: HTML 网页邮件已发送!");
            } catch (MessagingException e) {
                log.error("[邮件发送]: HTML 网页邮件发送异常, {}", e.getMessage());
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    4. 工具类测试及效果演示

        在src/test/ 下新建测试类SMTPEmailUtilTest.java
        测试发送附件的方法

    @Test
    public void sendEmailByEnclosure() {
        List<String> receiverList = Arrays.asList("22221111@163.com");
        List<String> carbonCopyList = Arrays.asList("22221111@qq.com");
        String subject = "宝儿姐喊你查阅附件";
        String content = "<img width=\"300\" height=\"400\" src=\"https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1564045091&di=57335f2e16c0a670b26c72aa9eb61b0c&src=http://imglf5.nosdn.127.net/img/UUZTMkZCa0pWZEE1Ri9yT1Rhc0hmMnUzdU1KellDZTNOOE1WMlE3N01XMCtrdm1HM0pSZVFBPT0.jpg?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg\"/>";
        // 项目内相对路径
        String smtpFileUrl = "src\\main\\resources\\static\\smtp.properties";
        // 本机D盘文件
        String LocalFileUrl = "D:\\download\\原始数据.csv";
        List<String> fileDataSourceList = Arrays.asList(smtpFileUrl, LocalFileUrl);
        SMTPEmailUtil.sendEmailByEnclosure(subject, content, fileDataSourceList, receiverList, carbonCopyList,null,null);
    }
    

        测试结果如图所示
    在这里插入图片描述

    图4-1.邮件发送工具类部分方法测试图

    在这里插入图片描述

    图4-2.测试发送邮件成功图

    5. 邮件发送API 测试及效果演示

        在src/main/java/pers/niaonao/email/web 下新建EmailController.java
        测试邮件发送接口

    @PostMapping("/sendEmailByEnclosure")
    public String sendEmailByEnclosure(@RequestBody EmailRequestVo emailRequest){
        if (StringUtils.isEmpty(emailRequest.getSubject())){
            return "请维护邮件主题!";
        }
        if (CollectionUtils.isEmpty(emailRequest.getFileUrlList())) {
            return "请添加附件!";
        }
        if (CollectionUtils.isEmpty(emailRequest.getReceiverList())) {
            return "请维护收件人!";
        }
        SMTPEmailUtil.sendEmailByEnclosure(emailRequest.getSubject(), emailRequest.getHtml(), emailRequest.getFileUrlList(), emailRequest.getReceiverList(), emailRequest.getCarbonCopyList(), emailRequest.getBlindCarbonCopyList(), emailRequest.getSendDate());
        return "发送完成!";
    }
    

        使用postman 调用接口发送邮件成功图
    在这里插入图片描述

    图5-1.Postman 测试邮件发送API 图

    收件如下
    在这里插入图片描述

    图5-2.Postman 调用接口发送邮件成功图
    The End.
    展开全文
  • 邮件协议详解

    千次阅读 2021-07-22 15:31:29
    电子邮件发送协议 是一种基于“ 推 ”的协议,主要包括 SMTP ; 邮件接收协议 则是一种基于“ 拉 ”的协议,主要包括 POP协议 和 IMAP协议 ,在正式介绍这些协议之前,我们先给出邮件收发的体系结构: 从上图...
  • 邮件服务器协议

    千次阅读 2021-08-10 08:31:35
    邮件服务器协议 内容精选换一换浏览器发送邮件:在使用浏览器登录邮箱时直接使用HTTP协议,其端口号默认为80,邮件服务器之间还是使用邮件发送协议:SMTP协议。通过浏览器发送邮件,则需要开放TCP出方向端口为80。在...
  • java邮件发送

    千次阅读 2022-04-06 16:18:16
    JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail ...
  • 电子邮件是通过网络发送、存储和检索电子邮件的存储转发方法。 电子邮件存储在邮件服务器的数据库中。ISP 维护的邮件服务器一般可支持大量用户帐户。电子邮件客户端通过与邮件服务器通信来收发电子邮件邮件服务器...
  • 用户A向用户B发送邮件,首先用户A利用由用户代理撰写邮件,包括填写收件人邮箱地址等,然后基于SMTP将邮件发送到其注册的邮箱服务器A的外出邮件列队中,等待邮件服务器A依次从列队中取出邮件,并基于SMTP发送邮件。...
  • 基于JavaMail的Java邮件发送:简单邮件发送

    万次阅读 多人点赞 2016-06-14 21:56:35
    电子邮件的应用非常广泛,例如在某网站注册了一个...但这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件发送。本文将简单介绍如何通过 Java 代码来创建电子邮件,并连接邮件服务器发...
  •  3 服务器发送回250代表请求成功 3.开始登陆自己的账号 //先开始输入授权命令,在输入经过base64处理的邮箱账号和授权码 //账号和密码都需要经过base64处理 auth login 334 VXN1...U6 email address converted by ...
  • 电子邮件发送协议是一种基于“推”的协议,主要包括SMTP;邮件接收协议则是一种基于“拉”的协议,主要包括POP协议和IMAP协议,在正式介绍这些协议之前,我们先给出邮件收发的体系结构: 从上图可以看出邮件...
  • 电子邮件--详解SMTP和POP3协议

    千次阅读 2021-10-11 16:19:06
    邮件系统的组成结构二、SMTP协议1.协议概述2.通信过程(1)连接建立(2)邮件传送(3)连接释放三、POP3协议总结 前言 提示:以下是本篇文章正文内容 一、电子邮件概述 1.邮件信息格式 一个电子邮件分为信封和内容,...
  • 文章目录文件传输协议FTP的工作原理控制连接与数据连接控制连接数据连接电子邮件电子邮件系统的组成结构电子邮件格式与MIME电子邮件格式多用途网际邮件扩充MIMESMTP和POP3SMTPPOP3和IMAP万维网WWWWWW的概念与组成...
  • 基于JavaMail的Java邮件发送:复杂邮件发送

    万次阅读 多人点赞 2016-06-20 23:11:52
    上一篇文章 基于 JavaMail 的 Java 邮件发送:简单邮件发送 讲解了邮件的基本协议,JavaMail组件,创建并发送一封简单邮件的详细步骤。本文将介绍如何创建并发送一封包含图片和附件的复杂邮件。 一封复杂的邮件内容...
  • 一、 邮件开发涉及到的一些基本概念 1.1、邮件服务器和电子邮箱  要在Internet上提供电子邮件功能,...例如现在Internet很多提供邮件服务的厂商:sina、sohu、163等等他们都有自己的邮件服务器。  这些邮件...
  • TCP/IP (Transmission Control Protocol/Internet Protocol),传输控制协议/网际协议,它是在网络使用中最基本的通信协议,TCP/IP协议不仅仅指的是TCP和IP两个协议,而是指一个由TCP、IP、HTTP、FTP等协议构成的协议...
  • 使用python进行邮件发送

    千次阅读 多人点赞 2022-02-04 13:40:15
    发送邮件和退出邮箱三.定时发送四.效果 前言 如果你和我一样偶尔看看股票,看看自己关注的股票是涨了还是跌了,或者想快速获取到想看的头条新闻,我们不必把过多的注意力放在去寻找上面,我们只需要让爬虫程序每天...
  • JAVA实现邮件发送

    万次阅读 多人点赞 2020-07-04 22:52:37
    一、邮件服务器与传输协议 要在网络上实现邮件...SMTP协议:通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。 POP3协议:通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP
  • Java邮件发送详解

    万次阅读 多人点赞 2019-07-19 13:37:34
    电子邮件 要在网络上实现邮件功能,必须要有专门的邮件服务器。 这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。 SMTP服务器地址:一般是 smtp....
  • 一、常用的电子邮件协议 常用的电子邮件协议有SMTP、POP3、IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别通过TCP端口25、110和143建立连接。下面分别对其进行简单介绍 1.1、SMTP协议 SMTP的全称是...
  • 邮件访问协议!IMAP协议解析

    千次阅读 2021-03-07 16:59:26
    当我们所做的选择那种电子件协议,将对您发送,接收和以其他方式使用电子邮件的体验有一定影响。 POP(邮局协议)曾经是电子邮件协议中最流行的类型,但如今,IMAP是大多数人的首选。在下面详细了解IMAP是什么,以及...
  • 我们使用邮件一般是使用邮件客户端,比如,Thunderbird,Foxmail,Microsoft Outlook等等,使用的时候需要设置STMP发送服务器,POP3或者IMAP接收服务器这样给我们的印象似乎是STMP是发送协议,POP3或者IMAP是接收协议。...
  • SpringBoot 发送邮件和附件

    千次阅读 2019-01-22 16:29:41
    作者:yizhiwazi ... SpringBoot集成邮件服务竟如此简单,还等什么... SMTP全称为Simple Mail Transfer Protocol(简单邮件传输协议),它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。...
  • python实现smtp协议发送邮件

    千次阅读 2018-09-10 18:37:48
     (1) SMTP协议(simple mail transfer protocol) 简单邮件传输协议  (2) 定义了邮件客户端与SMTP服务器之间、两台SMTP服务器之间的通信规则  (3) 分为标准SMTP协议和扩展SMTP协议。扩展SMTP协议在标准SMTP协议上...
  • Java实现邮件发送

    万次阅读 多人点赞 2019-07-20 16:03:19
    Java实现邮件发送 一、邮件服务器与传输协议 要在网络上实现邮件功能,必须要有专门的邮件服务器。这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱...
  • 邮件发送接收原理

    千次阅读 2018-05-24 22:26:24
    当你发送一封邮件的时候,它首先会发送到收件人的邮件服务器上,并放入收件人的信箱中。(如果你在某一个邮件服务器提供商那里申请了一个邮箱账号,那么你在这个邮件服务器上面就有一个电子信箱)。收件人只需要定时...
  • 邮件协议POP3/IMAP/SMTP介绍

    万次阅读 2020-06-06 16:06:47
    一、邮件发送、收取过程 图示的六个步骤分别进行如下的说明:  ①、用户A的电子邮箱为:xx@qq.com,通过邮件客户端软件写好一封邮件,交到QQ的邮件服务器,这一步使用的协议是SMTP,对应图示的①;  ②、QQ...
  • 使用SMTP协议发送邮件

    千次阅读 2018-10-18 19:03:00
    邮件发送,主要是通过SMTP协议来实现的 一、使用telnet工具使用SMTP协议发送邮件 1、使用 telnet 连接邮件服务器25端口 [root@17:10:48 ~]# telnet mail.domain.com 25 Trying 192.168.1.121... Connect...
  • 电子邮件协议之SMTP、POP3和IMAP

    万次阅读 多人点赞 2018-06-15 09:00:24
    本文转自https://blog.csdn.net/ladybai/article/details/50988205首先,来...图1:电子邮件协议及其通信实体其中,在接收端邮件服务器(E-mail Server)与接收用户代理(User Agent)之间常用的协议有:POP3(Post ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 108,314
精华内容 43,325
热门标签
关键字:

处理邮件发送请求的协议是