zoukankan      html  css  js  c++  java
  • java实现POP3邮件客户端

    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  * @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+"
    ";    
    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+"
    ";
    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的输入输出流真的比较多,有点不好记,但是每个输出流的原理是一样,而且有封装的特性。接下来一定要狠狠的把它搞懂了!

     

     

     

  • 相关阅读:
    react native android 应用状态(前端或后台)的判断
    react native native module
    Nodejs项目重复文件扫描
    clipboard.js文本复制到剪贴板的现代方法
    微信小程序如何跳转到另一个小程序
    百度小程序button去掉默认边框
    下拉框select中option居中样式
    css中如何实现左边的高度随着右边改变而改变
    js判断是否手机自动跳转移动端
    webpack安装整理
  • 原文地址:https://www.cnblogs.com/hewenwu/p/3713236.html
Copyright © 2011-2022 走看看