博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java实现POP3邮件客户端
阅读量:6008 次
发布时间:2019-06-20

本文共 8949 字,大约阅读时间需要 29 分钟。

java实现POP3邮件客户端

 

完整项目包: (提取码: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  * @author hewenwu  3  * 这个程序实现了基于POP3协议的邮件接收功能  4  * */  5 package mail;  6   7 import java.io.BufferedReader;  8 import java.io.BufferedWriter;  9 import java.io.IOException; 10 import java.io.InputStreamReader; 11 import java.io.OutputStreamWriter; 12 import java.io.UnsupportedEncodingException; 13 import java.net.Socket; 14 import java.net.UnknownHostException; 15 import java.util.StringTokenizer; 16  17 public class POP3Client { 18  19     private Socket socket = null; 20   21     private boolean debug=true; 22   23     public static void main(String[] args) throws UnknownHostException, 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) throws UnknownHostException, 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 boolean recieveMail(String user,String password){ 55              56         try { 57                 BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); 58         59                 BufferedWriter out=new BufferedWriter(new OutputStreamWriter(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     public String 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         return line;111     }112  113     //从返回的命令中得到第一个字段,也就是服务器的返回状态码(+OK或者-ERR)114     public String getResult(String line){115 116         StringTokenizer st=new StringTokenizer(line," ");117 118         return st.nextToken();119     }120  121     //发送命令122     private String sendServer(String str,BufferedReader in,BufferedWriter out) throws IOException{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          return getReturn(in);135      }136  137     //user命令138     139     public void user(String user,BufferedReader in,BufferedWriter out) throws IOException{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) throws IOException{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) throws IOException{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         return mailNum;205  }206     207         //无参数list命令208         public void list(BufferedReader in,BufferedWriter out) throws IOException{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+"\n";    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) throws IOException{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) throws UnsupportedEncodingException{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+"\n";253    254                 line=in.readLine().toString();255             }256         }catch(Exception e){257   258             e.printStackTrace();259         }260     261             return message;262     }263  264  //retr命令265     public void retr(int mailNum,BufferedReader in,BufferedWriter out) throws IOException, 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) throws IOException{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的输入输出流真的比较多,有点不好记,但是每个输出流的原理是一样,而且有封装的特性。接下来一定要狠狠的把它搞懂了!

 

 

 

 

转载于:https://www.cnblogs.com/hewenwu/p/3713236.html

你可能感兴趣的文章
ASP生成静态页面的方法
查看>>
mysql 权限
查看>>
HDU 1325 Is It A Tree? 判断是否为一棵树
查看>>
Shell命令-文件压缩解压缩之gzip、zip
查看>>
个人总结
查看>>
uva 673 Parentheses Balance
查看>>
申请Let’s Encrypt免费证书,给自己网站增加https访问
查看>>
javascript+html 实现隐藏 显示
查看>>
BZOJ 2120 数颜色
查看>>
正则表达式学习笔记——基础知识
查看>>
织梦如何实现二级栏目导航的仿制
查看>>
网上购物系统(Task010)——FormView编辑更新商品详细信息
查看>>
Struts2 技术全总结 (正在更新)
查看>>
PowerShell_零基础自学课程_5_自定义PowerShell环境及Powershell中的基本概念
查看>>
Bzoj 2252: [2010Beijing wc]矩阵距离 广搜
查看>>
《编程之美》——寻找发帖“水王”学习与扩展 转surymj博客
查看>>
Linux 虚拟机VMware安装失败,提示没有选择磁盘
查看>>
LeetCode-Permutations
查看>>
C#整数三种强制类型转换int、Convert.ToInt32()、int.Parse()的区别
查看>>
css 禁止选中文本
查看>>