java实现POP3邮件客户端

摘要:
2) 如果服务器处于“身份验证”状态,则结束会话并退出连接代码:1/***2*@authorhewenwu3*此程序实现基于POP3协议的邮件接收功能4**/5 packagemail;67导入java.io。缓冲读取器;8导入java.io。BufferedWriter;9导入java.io。IO异常;10导入java.io。输入流阅读器;11导入java.io。OutputStreamWriter;12导入java.io。不支持的EncodingException;13导入java.net。插座14导入java.net。未知主机异常;15导入java.util。StringTokenizer;1617publicclassPOP3Client{1819privateSocketsocket=null;2021privatepoolendbug=true;2223publicstaticvoidmaintthrowsUnknownHostException,IOException{2425Stringserver=“pop3.163.com”;//pop3服务器地址2627Stringuser=“****************”;//用户名,填写您的电子邮件用户名2829Stringpassword=“*******” ;// 密码,填写您自己的密码3031POP3Clientop3Client=newPOP3Client;3233pop3客户端。receiveMail;34}3536/*构造函数*/37publicPOP3ClientThrowsUnknownHostException,IOException{38try{3940socket=newSocket;//已与服务器4142}catch{4344e.printStackTrace();4546}最后{4748System.out.println(“建立连接!

java实现POP3邮件客户端

完整项目包:http://yunpan.cn/QiVGqacT6uNAj (提取码:05b4)

第一步:利用socket编程,在客户端与服务器端之间建立TCP连接,POP3默认端口号为110;

第二步:通过pop3定义的各种命令,用户可以操作自己的邮箱。

注:

POP3协议中有三种状态,认正状态,处理状态,和更新状态。命令的执行可以改变协议的状态,而对于具体的某命令,它只能在具体的某状态下使用,这些请参看表1和RFC193。

客户机与服务器刚与服务器建立连接时,它的状态为认证状态;一旦客户机提供了自己身份并被成功地确认,即由认可状态转入处理状态;在完成相应的操作后客户机发出QUIT命令(具体说明见后续内容),则进入更新状态,更新之后又重返认可状态;当然在认可状态下执行QUIT命令,可释放连接。状态间的转移如图1所示。

---建立连接---|认可|--认证成功--|处理|--执行QUIT--|更新|

|_______-QUIT结束_________________|

ddddddd

常用命令:

命令

参数

使用在何种状态中

描述

USER

Username

认证

此命令与下面的pass命令若成功,将导致状态转换

PASS

Password

认证

此命令若成功,状态转化为更新

APOP

Name,Digest

认证

Digest是MD5消息摘要

STAT

None

处理

请求服务器发回关于邮箱的统计资料,如邮件总数和总字节数

UIDL

[Msg#](邮件号,下同)

处理

返回邮件的唯一标识符,POP3会话的每个标识符都将是唯一的

LIST

[Msg#]

处理

返回邮件的唯一标识符,POP3会话的每个标识符都将是唯一的

RETR

[Msg#]

处理

返回由参数标识的邮件的全部文本

DELE

[Msg#]

处理

服务器将由参数标识的邮件标记为删除,由QUIT命令执行

TOP

[Msg#]

处理

服务器将返回由参数标识的邮件的邮件头+前n行内容,n必须是正整数

NOOP

None

处理

服务器返回一个肯定的响应,用于测试连接是否成功

QUIT

None

处理、认证

1)如果服务器处于“处理”状态,么将进入“更新”状态以删除任何标记为删除的邮件,并重返“认证”状态。

2)如果服务器处于“认证”状态,则结束会话,退出连接

代码:

1 /**
2 * @authorhewenwu
3 * 这个程序实现了基于POP3协议的邮件接收功能
4 * */
5 packagemail;
6 
7 importjava.io.BufferedReader;
8 importjava.io.BufferedWriter;
9 importjava.io.IOException;
10 importjava.io.InputStreamReader;
11 importjava.io.OutputStreamWriter;
12 importjava.io.UnsupportedEncodingException;
13 importjava.net.Socket;
14 importjava.net.UnknownHostException;
15 importjava.util.StringTokenizer;
16 
17 public classPOP3Client {
18 
19     private Socket socket = null;
20  
21     private boolean debug=true;
22  
23     public static void main(String[] args) throwsUnknownHostException, IOException {
24   
25         String server="pop3.163.com";//POP3服务器地址
26   
27         String user="**********";//用户名,填写自己的邮箱用户名
28   
29         String password="*********";//密码,填写自己的密码
30  
31         POP3Client pop3Client=new POP3Client(server,110);
32  
33 pop3Client.recieveMail(user,password);
34 }
35  
36     /*构造函数*/
37     public POP3Client(String server,int port) throwsUnknownHostException, IOException{
38         try{
39    
40             socket=new Socket(server,port);//在新建socket的时候就已经与服务器建立了连接
41 
42         }catch(Exception e){
43    
44 e.printStackTrace();
45  
46         }finally{
47  
48             System.out.println("建立连接!");
49 }
50 }
51  
52     
53     //接收邮件程序
54     public booleanrecieveMail(String user,String password){
55             
56         try{
57                 BufferedReader in=new BufferedReader(newInputStreamReader(socket.getInputStream()));
58        
59                 BufferedWriter out=new BufferedWriter(newOutputStreamWriter(socket.getOutputStream()));
60       
61                 user(user,in,out);//输入用户名
62        
63                 System.out.println("user 命令执行完毕!");
64                 
65                 pass(password,in,out);//输入密码
66       
67                 System.out.println("pass 命令执行完毕!");
68       
69 stat(in,out);
70       
71                 System.out.println("stat 命令执行完毕!");
72                 
73 list(in,out);
74                   
75                 System.out.println("list 命令执行完毕!");
76                 
77                 retr(2,in,out);
78                 
79                 System.out.println("retr 命令执行完毕!");
80       
81 quit(in,out);
82                 
83                 System.out.println("quit 命令执行完毕!");
84      
85             }catch(Exception e){
86       
87 e.printStackTrace();
88       
89                 return false;
90 }
91             return true;
92 }
93     
94     //得到服务器返回的一行命令
95     publicString getReturn(BufferedReader in){
96     
97         String line="";
98   
99         try{
100             line=in.readLine();
101    
102             if(debug){
103    
104                 System.out.println("服务器返回状态:"+line);
105 }
106         }catch(Exception e){
107  
108 e.printStackTrace();
109 }
110         returnline;
111 }
112  
113     //从返回的命令中得到第一个字段,也就是服务器的返回状态码(+OK或者-ERR)
114     publicString getResult(String line){
115 
116         StringTokenizer st=new StringTokenizer(line," ");
117 
118         returnst.nextToken();
119 }
120  
121     //发送命令
122     private String sendServer(String str,BufferedReader in,BufferedWriter out) throwsIOException{
123         
124         out.write(str);//发送命令
125  
126         out.newLine();//发送空行
127  
128         out.flush();//清空缓冲区
129   
130         if(debug){
131   
132             System.out.println("已发送命令:"+str);
133 }
134          returngetReturn(in);
135 }
136  
137     //user命令
138     
139     public void user(String user,BufferedReader in,BufferedWriter out) throwsIOException{
140 
141         String result = null;
142  
143         result=getResult(getReturn(in));//先检测连接服务器是否已经成功
144  
145         if(!"+OK".equals(result)){
146    
147             throw new IOException("连接服务器失败!");
148 }
149  
150         result=getResult(sendServer("user "+user,in,out));//发送user命令
151 
152         if(!"+OK".equals(result)){
153   
154             throw new IOException("用户名错误!");
155 }
156 }
157  
158     //pass命令
159     public void pass(String password,BufferedReader in,BufferedWriter out) throwsIOException{
160  
161         String result = null;
162  
163         result = getResult(sendServer("pass "+password,in,out)); 
164  
165         if(!"+OK".equals(result)){
166 
167             throw new IOException("密码错误!");
168 }
169 }
170 
171     
172     //stat命令
173 
174     public int stat(BufferedReader in,BufferedWriter out) throwsIOException{
175  
176         String result = null;
177  
178         String line = null;
179   
180         int mailNum = 0;
181  
182         line=sendServer("stat",in,out); 
183  
184         StringTokenizer st=new StringTokenizer(line," ");
185   
186         result=st.nextToken();
187   
188         if(st.hasMoreTokens())
189  
190             mailNum=Integer.parseInt(st.nextToken());
191  
192         else{
193             
194             mailNum=0;
195             
196 }
197         
198         if(!"+OK".equals(result)){
199  
200             throw new IOException("查看邮箱状态出错!");
201 }
202  
203         System.out.println("共有邮件"+mailNum+"封");
204         returnmailNum;
205 }
206     
207         //无参数list命令
208         public void list(BufferedReader in,BufferedWriter out) throwsIOException{
209      
210             String message = "";
211      
212             String line = null;
213      
214             line=sendServer("list",in,out); 
215      
216             while(!".".equalsIgnoreCase(line)){
217        
218                 message=message+line+"
";    
219             
220                 line=in.readLine().toString();
221 }
222             
223 System.out.println(message);
224 }
225         
226           //带参数list命令
227                 public void list_one(int mailNumber ,BufferedReader in,BufferedWriter out) throwsIOException{
228 
229                     String result = null;
230                      
231                     result = getResult(sendServer("list "+mailNumber,in,out)); 
232              
233                     if(!"+OK".equals(result)){
234 
235                         throw new IOException("list错误!");
236 }
237 }
238  
239  //得到邮件详细信息
240  
241     public String getMessagedetail(BufferedReader in) throwsUnsupportedEncodingException{
242  
243         String message = "";
244   
245         String line = null;
246  
247         try{
248             line=in.readLine().toString();
249   
250             while(!".".equalsIgnoreCase(line)){
251    
252                 message=message+line+"
";
253    
254                 line=in.readLine().toString();
255 }
256         }catch(Exception e){
257   
258 e.printStackTrace();
259 }
260     
261             returnmessage;
262 }
263  
264  //retr命令
265     public void retr(int mailNum,BufferedReader in,BufferedWriter out) throwsIOException, InterruptedException{
266   
267             String result = null;
268    
269             result=getResult(sendServer("retr "+mailNum,in,out));
270   
271             if(!"+OK".equals(result)){
272   
273                 throw new IOException("接收邮件出错!");
274 }
275             
276             System.out.println("第"+mailNum+"封");
277 System.out.println(getMessagedetail(in));
278             Thread.sleep(3000);
279 }
280  
281     //退出
282     public void quit(BufferedReader in,BufferedWriter out) throwsIOException{
283  
284 String result;
285  
286         result=getResult(sendServer("QUIT",in,out));
287  
288         if(!"+OK".equals(result)){
289   
290             throw new IOException("未能正确退出");
291 }
292 }
293  
294 }

总结:

这个项目其实非常简单,关键要理解两个方面,一是怎么利用socket编程连接到服务器,二是POP3协议命令的格式和返回值的格式。理解了这两个方面,就好做了。首先建立连接,然后通过socket对象获取输入输出流对象,在输入输出流对象上发送命令和接受返回值,接收到返回值之后自己本地处理这些返回值就行啦。

说到输入输出流,java的输入输出流真的比较多,有点不好记,但是每个输出流的原理是一样,而且有封装的特性。接下来一定要狠狠的把它搞懂了!

免责声明:文章转载自《java实现POP3邮件客户端》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇新东方在有状态服务 In K8s 的实践鸟叔学Windows8开发(1):自定义弹出窗口下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

asp.net mvc+EF 递归生成树结构返回json

0、数据表结构,主要属性有:Id、parentId(父节Id)、Text、Url……等等。 1、新建一个树结构MenuModels 1 public class MenuModels 2 { 3 private int _id; 4 private string _text; 5...

Java上传图片到Ftp,包含上传后文件大小为0的问题和Properties配置文件的读取

准备工作:需要使用coomos-net jar包。下载地址 一、 上传图片到FTP,文件大小为0的问题,解决:将ftp模式修改为Passive模式就可以了。 //将ftp模式修改为Passive模式 ftpClient.enterLocalPassiveMode(); 二、配置文件的操作,具体介绍请看 Java中Properties类的用法总结 1.使用...

照片上传(缩略图实现)

1.获取所有的提交到服务器的文件集合 HttpFileCollection fileColl= Request.Files; 2.取得一个文件(这里是一张照片)     HttpPostedFile pic = fileColl[0]; 3.判断文件是否为空     1.获取服务器存放图片的物理路径(Server.MapPath)        strin...

读取FTP上的excel文件,并写入数据库

今天遇到一些问题,需要从ftp上读取一些excel文件,并需要将excel中的数据写入到数据库,这样就可以通过管理页面查看这些数据。 我将相关工作分为三步,1、从ftp上读取相关文件,并将excel文件下载到本地。2、读取本地下载完成的excel,读取相关信息 3、将读取的信息存储到数据库中。 1、获取java操作ftp操作,首先要从maven仓库http...

.NET Core+QQ第三方授权登录

安装包 dotnet add package AspNet.Security.OAuth.QQ 接上文GitHub第三方授权登录 申请过程不介绍了,申请者资料,个人也是可以申请成功的。 这时候有二个参数就是clientid clientsecret APP ID:xxxx APP Key:xxxxxx 其中平台信息,这个申请审核通过后,不要修改,千万不...

Vert X 干法总结

Vert X优势:   1. 与基于阻塞 I/O 的传统堆栈和框架相比,以更少的资源处理更多的请求。Vert.x 非常适合各种执行环境,包括虚拟机和容器等受限环境。   2. Vert.x 是一个工具包,不是一个框架,所以它自然是非常可组合和可嵌入的(不同语言都可以)。     Vert.x运行在Java虚拟机上,支持多种编程语言,Vert.x是高度模块化...