搜索
查看: 823|回复: 1

[扩展库] 异步POP3客户端

  [复制链接]

2

主题

9

帖子

145

积分

一级会员

Rank: 2

积分
145
发表于 2018-8-11 00:45:43 | 显示全部楼层 |阅读模式
工作需要自动审邮件,故写了个POP3客户端接收邮件,基于HPSocket,支持SSL。
由于时间关系,很多特性没有测试,也有很多不规范的地方,有需要的就自行修改吧。
SSL有问题的话请先更新HPSocket库。

没找到附件按钮,所以用了自己服务器的链接,不定时删除。
库文件下载地址;demo下载地址

以下是库的原煤
  1. import hpsocket.ssl.tcpPullClient;
  2. import hpsocket.tcpPullClient;
  3. import thread.table;

  4. HP_POP3 = class {
  5.         ctor( server,user,pw,ssl,port,vMode,certFile,keyFile,certPW,ca){
  6.                 this.server = server;
  7.                 this.port = port:(ssl?995:110);
  8.                 this.user = user;
  9.                 this.pw = pw;
  10.                
  11.                 this.connected = false;
  12.                 this.statue = 'Init';
  13.                 this.login = false;
  14.                 this.Queue = {};//队列消息
  15.                 this.runTask = null//当前任务
  16.                
  17.                 var socket = ssl?..hpsocket.ssl.tcpPullClient():..hpsocket.tcpPullClient();
  18.                 if !socket return null;

  19.                 if (ssl) {
  20.                         socket.sslSetupContext(vMode:0x0,certFile,keyFile,certPW,ca);
  21.                 }

  22.                 socket.setSocketBufferSize(65536);//64KB:MAX
  23.                
  24.                 this.socket = socket;
  25.                 this.msgcount = 0;
  26.                
  27.                 this._form = ..win.form();//创建回调窗体
  28.                 this._form.messageOnly();
  29.                
  30.                 this._form.wndproc = function(hwnd,message,wParam,lParam){//回调消息处理过程
  31.                         select (message - 0x400/*_WM_USER*/){
  32.                                 case 1 { //connected
  33.                                         this.onConnect(wParam);
  34.                                 }
  35.                                 case 2 { //closed
  36.                                         this.onClosed(wParam,lParam)
  37.                                 }
  38.                                 case 3 {  //sent
  39.                                         this.onSent(topointer(wParam),lParam)
  40.                                 }
  41.                                 case 4 { //Peek_Received
  42.                                         return this.onPeekRecv(topointer(wParam),lParam)
  43.                                 }
  44.                                 case 5 { //Timer Out
  45.                                         if (lParam) this.timerHwnd = topointer(lParam);
  46.                                         var msg = pString(topointer(wParam))
  47.                                         if (#msg) this.onTimeOut(msg,lParam);
  48.                                 }
  49.                                 case 6 { //Fetch Receive
  50.                                         if (lParam != 0) {
  51.                                                 this.onDataRecv(topointer(wParam),lParam);
  52.                                         }
  53.                                         else {
  54.                                                 if (this.onDebug) this.onDebug("Fectch Err",wParam);
  55.                                         }
  56.                                 }
  57.                         }
  58.                 }
  59.                
  60.                 var thrTable = ..thread.table("HP_POP3",true)
  61.                 thrTable.hwnd = this._form.hwnd;
  62.                
  63.                 this.timerThread =
  64.                         ..thread.create(
  65.                         function(hwnd){
  66.                                 import win.ui;
  67.                                 import console;
  68.                                 timerForm = ..win.form();//定时器窗体
  69.                                 timerForm.messageOnly();
  70.                                
  71.                                 var timer = {
  72.                                         [1] = { lasttime = 0;        msg = "package_timeout"};
  73.                                         [2] = {        lasttime = 0;        msg = "receive_timeout"};
  74.                                         [3] = {        lasttime = 0;        msg = "session_timeout"};
  75.                                 };
  76.                                 var running = true;
  77.                                
  78.                                 var msgHwnd = hwnd;
  79.                                
  80.                                 timerForm.wndproc = function(hwnd,message,wParam,lParam){//回调消息处理过程
  81.                                         var wParam,delay = msg,lParam;
  82.                                         var uMsg = (message - (0x400/*_WM_USER*/ + 10))
  83.                                        
  84.                                         select (uMsg){
  85.                                                 case (0){//退出
  86.                                                         running = false;
  87.                                                 }
  88.                                                 case 1,2,3{//设置第1/2/3个定时器
  89.                                                         timer[uMsg].lasttime = delay?(time.tick() + delay):0;
  90.                                                 }
  91.                                         }
  92.                                 }
  93.                                
  94.                                 ::User32.SendMessage(msgHwnd,0x400/*_WM_USER*/ + 5,"",timerForm.hwnd);
  95.                                 while(running){
  96.                                         for i=1;#timer;1{
  97.                                                 if timer[i].lasttime != 0{
  98.                                                         if time.tick() >= timer[i].lasttime{
  99.                                                                 ::User32.SendMessageA(msgHwnd,0x400/*_WM_USER*/ + 5,timer[i].msg,i);
  100.                                                                 timer[i].lasttime = 0
  101.                                                         }
  102.                                                 }       
  103.                                         }
  104.                                         win.delay(100);
  105.                                 }
  106.                         },this._form.hwnd)
  107.                
  108.                 this.package_timeout = 5000;
  109.                 this.statue_timeout = 20000;
  110.                
  111.                 ..table.gc(this,"destroy");
  112.         }
  113.         onHPConnect = function(hpTcpClient,connId){//HPConnect线程回调
  114.                 import thread.table;
  115.                 var thrTable = thread.table("HP_POP3");
  116.                 var hwnd = thrTable.hwnd;
  117.                 ::User32.SendMessage(hwnd,0x400/*_WM_USER*/ + 1,connId,0);
  118.         }
  119.         onHPClose = function(hpTcpClient,connId,enOperation,errCode){//HPClose线程回调
  120.                 import thread.table;
  121.                 var thrTable = thread.table("HP_POP3");
  122.                 var hwnd = thrTable.hwnd;
  123.                 ::User32.SendMessage(hwnd,0x400/*_WM_USER*/ + 2,enOperation,errCode);
  124.         }
  125.         onHPSend = function(hpTcpClient,connId,pData,length){//HPSend线程回调
  126.                 import thread.table;
  127.                 var thrTable = thread.table("HP_POP3");
  128.                 var hwnd = thrTable.hwnd;
  129.                 ::User32.SendMessage(hwnd,0x400/*_WM_USER*/ + 3,pData,length);
  130.         }
  131.         onHPPullReceive = function(hpTcpPullClient,connId,length){
  132.                 import thread.table;
  133.                 //---创建 buf 窥探数据 ------
  134.                 var buf = ..raw.malloc(length);
  135.                 hpTcpPullClient.peek(buf,length);
  136.                
  137.                 import thread.table;
  138.                
  139.                 var thrTable = thread.table("HP_POP3");
  140.                 var hwnd = thrTable.hwnd;
  141.                 if ( ::User32.SendMessage(hwnd,0x400/*_WM_USER*/ + 4,buf,length) ){
  142.                         //只要有返回值的时候,就默认为可以取出数据了
  143.                         buf = ..raw.malloc(length);
  144.                         var fetch_state = hpTcpPullClient.fetch(buf);
  145.                         //成功取出后,返回buf,len,否则返回statue,0;
  146.                         ::User32.SendMessage(hwnd,0x400/*_WM_USER*/ + 6,(fetch_state==0)?buf:fetch_state,(fetch_state==0)?length:0)
  147.                 }
  148.                 else {
  149.                         return 1; //继续缓存数据
  150.                 }
  151.         }
  152.         connect = function(user,pw,port,onLogin,onConn){
  153.                 this.user = user:this.user;
  154.                 this.pw   = pw:this.pw;
  155.                 this.port = port:this.port;
  156.                
  157.                 var socket = this.socket:..hpsocket.tcpPullClient();
  158.                 if !socket return null;
  159.                
  160.                 if (onLogin) this.onLogin = onLogin;//登录回调
  161.                 if (onConn)  this.onConn = onConn;//连接回调
  162.                 this.login = false;
  163.                
  164.                 socket.onConnect         = this.onHPConnect;
  165.                 socket.onSend                  = this.onHPSend;
  166.                 socket.onClose                  = this.onHPClose;
  167.                 socket.onPullReceive = this.onHPPullReceive;
  168.                
  169.                 this.statue = _POP_CONNTING;
  170.                 this.runTask = {
  171.                         ["statue"] = this.statue;
  172.                         ["data"] = {};
  173.                 }
  174.                 return socket.start(this.server,this.port)?true:false;
  175.         }
  176.         onConnect = function(connId){
  177.                 this.connected = true;
  178.                 if(this.onConn) this.onConn(connId);
  179.         }
  180.         onClosed = function(enOperation,errCode){
  181.                 if this.statue != _POP_CONN and this.statue != _POP_DISCONN{
  182.                         var task = this.runTask;
  183.                         task.err = msg;
  184.                        
  185.                         var text;
  186.                         if (task.recvLength) {
  187.                                 buf = ..raw.malloc(task.recvLength);
  188.                                 var fetch_state = this.socket.fetch(buf);
  189.                                 text = pString(buf,1,task.recvLength);
  190.                         }
  191.                        
  192.                         if (task.callback) task.callback(_STATE_DISCONN,text,task);
  193.                         this.loopMsg(true);
  194.                 }
  195.                 if (this.onClose) this.onClose(enOperation,errCode)
  196.                 this.setStatue(_POP_DISCONN);
  197.         }
  198.         onSent = function(pData,iLength){
  199.                 if (this.onSend) this.onSend(pData,iLength)
  200.         }
  201.         onTimeOut = function(msg,index){
  202.                 if this.statue != _POP_CONN and this.statue != _POP_DISCONN{
  203.                         var task = this.runTask;
  204.                         task.err = msg;
  205.                        
  206.                         var text;
  207.                         if (task.recvLength) {
  208.                                 buf = ..raw.malloc(task.recvLength);
  209.                                 var fetch_state = this.socket.fetch(buf);
  210.                                 text = pString(buf,1,task.recvLength);
  211.                         }
  212.                        
  213.                         if (task.callback) task.callback(_STATE_TIMEOUT,text,task);//不要随意改动task的位置,不然触发本事件会崩溃
  214.                         this.setStatue(this.login?_POP_CONN:_POP_DISCONN);
  215.                         this.loopMsg();
  216.                 }
  217.         }
  218.         setTimer = function(index,delay){
  219.                 ::User32.SendMessage(this.timerHwnd,(0x400/*_WM_USER*/ + 10 + index),null,delay)
  220.         }
  221.         setTimeOut = function(package_timeout,statue_timeout){
  222.                 this.package_timeout = package_timeout:this.package_timeout;
  223.                 this.statue_timeout = statue_timeout:this.statue_timeout;
  224.         }
  225.         logMsg = function(...){
  226.                 ..console.log(...)
  227.         }
  228.         onPeekRecv = function(pData,len){
  229.                 var recv_Head,recv_End,recv_PointEnd = getPackState(pData,len);
  230.        
  231.                 var task = this.runTask;
  232.                 task.recvLength = len;
  233.                 this.setTimer(1,this.package_timeout);//更新包接收超时;
  234.                
  235.                 select (this.statue){
  236.                         case _POP_CONNTING,_POP_LOGONUSER,_POP_LOGONPASS,_POP_QUIT,_POP_STAT,_POP_DELE {
  237.                                 if recv_End !== _CRLF return 0;
  238.                                 task.state = getHeadState(recv_Head);
  239.                         }
  240.                         case _POP_LIST,_POP_UIDL,_POP_RETR,_POP_TOP {
  241.                                 if getHeadState(recv_Head) == _STATE_OK {
  242.                                         if (task.endCRLF){
  243.                                                 if (recv_End !== _CRLF) return 0;
  244.                                         }
  245.                                         else {
  246.                                                 if (recv_PointEnd !== _POINTCRLF) return 0;
  247.                                         }
  248.                                 }
  249.                                 else {
  250.                                         if recv_End !== _CRLF return 0;
  251.                                 }
  252.                                 task.state = getHeadState(recv_Head);
  253.                         }
  254.                         //其它情况下,如Connected,直接取得数据
  255.                 }
  256.                
  257.                 return 1;
  258.         }
  259.         onDataRecv = function(pData,len){
  260.                 var recv_Head,recv_End,recv_PointEnd = getPackState(pData,len);
  261.                 var task = this.runTask;
  262.                 var socket = this.socket;
  263.                
  264.                 this.setTimer(2,0);//取消数据超时;
  265.                 //var recv = pString(pData,1,len);
  266.                 //this.logMsg(this.statue,"packRecv",len);
  267.                
  268.                 var stateErr = getHeadState(recv_Head);
  269.                 var callback = task.callback;
  270.                
  271.                 select (this.statue){
  272.                         case _POP_CONNTING {
  273.                                
  274.                                 if ( stateErr == _STATE_OK ){
  275.                                         this.setStatue(_POP_LOGONUSER);
  276.                                         socket.send(        this.buildCmd(this.statue,this.user)        )
  277.                                 }
  278.                                 else {
  279.                                         this.onLogin(stateErr,concat(this.statue," FAILD, SERVER REJECTED:",'\r\n',pString(pData,5,len)));
  280.                                 }
  281.                         }
  282.                         case _POP_LOGONUSER{
  283.                                
  284.                                 if ( stateErr == _STATE_OK ){
  285.                                         this.setStatue(_POP_LOGONPASS);
  286.                                         socket.send(        this.buildCmd(this.statue,this.pw)        )
  287.                                 }
  288.                                 else {
  289.                                         this.onLogin(stateErr,concat(this.statue," FAILD, SERVER REJECTED:",'\r\n',pString(pData,5,len)));
  290.                                 }
  291.                         }
  292.                         case _POP_LOGONPASS{
  293.                                
  294.                                 if ( stateErr == _STATE_OK){
  295.                                         this.login = true;
  296.                                         this.setStatue(_POP_CONN);
  297.                                         this.onLogin(stateErr,pString(pData,5,len))
  298.                                 }
  299.                                 else {
  300.                                         this.onLogin(stateErr,concat(this.statue," FAILD, SERVER REJECTED:",'\r\n',pString(pData,5,len)))
  301.                                 }       
  302.                         }
  303.                         case _POP_QUIT{
  304.                                
  305.                                 this.login = false;
  306.                                 this.setStatue(_POP_DISCONN);
  307.                                 if (callback) callback( stateErr,getHeadText(pData,len));
  308.                                 this.loopMsg();
  309.                         }
  310.                         case _POP_STAT{
  311.        
  312.                                 var headText = getHeadText(pData,len);
  313.                                 var num,size,errText = 0,0,headText
  314.                                
  315.                                 if ( stateErr == _STATE_OK){
  316.                                         num,size = splitText(headText);
  317.                                         num = tonumber(num,10);size = tonumber(size,10);
  318.                                         errText = null;
  319.                                 }

  320.                                 this.setStatue(_POP_CONN);
  321.                                 if (callback) callback(stateErr,num,size,errText);
  322.                                 this.loopMsg();
  323.                         }
  324.                         case _POP_LIST,_POP_UIDL{

  325.                                 var headText,nextPos = getHeadText(pData,len);
  326.                                
  327.                                 var num,totalLength,content = 0,0,headText;

  328.                                 var keyWord = "length";
  329.                                 if (this.statue == _POP_UIDL) keyWord = "key";
  330.                                
  331.                                 if ( stateErr == _STATE_OK ){
  332.                                         num,totalLength = splitText(headText);
  333.                                         num = tonumber(num,10);totalLength = tonumber(totalLength,10);
  334.                                         content = {};
  335.                                         var id,key;
  336.                                         for line in ..string.lines(pString(pData,nextPos,len),_CRLF) {
  337.                                                 if (line != "" && line != '.') {
  338.                                                         id,key = splitText(line);
  339.                                                         if (id == _POP_OK)  id,key = splitText(key);//只有一个返回值的情况下
  340.                                                        
  341.                                                         push(content,{        ["id"] = id;        [keyWord] = key;});
  342.                                                 }
  343.                                         }
  344.                                 }
  345.                                
  346.                                 this.setStatue(_POP_CONN);
  347.                                 if (callback) callback(stateErr,num,totalLength,content);
  348.                                 this.loopMsg();
  349.                         }
  350.                         case _POP_RETR,_POP_TOP{
  351.                                
  352.                                 var headText,nextPos = getHeadText(pData,len);
  353.                                
  354.                                 var totalLength,content = 0,headText
  355.                                 if (stateErr == _STATE_OK) {
  356.                                         totalLength = splitText(headText);
  357.                                         totalLength = tonumber(totalLength,10)
  358.                                         content = pString(pData,nextPos,len);
  359.                                 }
  360.        
  361.                                 this.setStatue(_POP_CONN);
  362.                                 if (callback) callback(stateErr,task.id,totalLength,content);
  363.                                 this.loopMsg();
  364.                         }
  365.                         case _POP_DELE{
  366.                                
  367.                                 var headText = getHeadText(pData,len);

  368.                                 this.setStatue(_POP_CONN);
  369.                                 if (callback) callback(stateErr,task.id,headText);
  370.                                 this.loopMsg();
  371.                         }
  372.                         case _POP_DISCONN{
  373.                                
  374.                                 this.login = false;
  375.                                 if (callback) callback(_POP_DISCONN,task);
  376.                         }
  377.                         else {
  378.                                 //this.logMsg(pString(pData,1,len))
  379.                                 if (this.onDebug) this.onDebug(this.statue,task,pData,len)
  380.                         }
  381.                 }
  382.         }
  383.         stat = function(onStat){
  384.                 if (!this.login) return false,_POP_NOTREADY;
  385.                
  386.                 return this.addCmd(_POP_STAT,,onStat),this.loopMsg();//返回msgId,发送状态(发送结果/队列中/未登录)
  387.         }
  388.         list = function(id,onList){
  389.                 if (!this.login) return false,_POP_NOTREADY;
  390.                
  391.                 return this.addCmd(_POP_LIST,id,onList),this.loopMsg();
  392.         }
  393.         uidl = function(id,onUidl){
  394.                 if (!this.login) return false,_POP_NOTREADY;

  395.                 return this.addCmd(_POP_UIDL,id,onUidl),this.loopMsg();
  396.         }
  397.         retr = function(id,onRetr){
  398.                 if (!this.login) return false,_POP_NOTREADY;
  399.                 if !#tostring(id:"") return false,_POP_NEEDID;
  400.                
  401.                 return this.addCmd(_POP_RETR,id,onRetr),this.loopMsg();
  402.         }
  403.         quit = function(onQuit){
  404.                 if (!this.login) return false,_POP_NOTREADY;
  405.                
  406.                 return this.addCmd(_POP_QUIT,,onQuit),this.loopMsg();
  407.         }
  408.         top = function(id,linenum = 1,onTop){
  409.                 if (!this.login) return false,_POP_NOTREADY;
  410.                 if !#tostring(id:"") return false,_POP_NEEDID;
  411.                
  412.                 return this.addCmd(_POP_TOP,id,onTop,concat(" ",linenum)),this.loopMsg();
  413.         }
  414.         dele = function(id,onDele){
  415.                 if (!this.login) return false,_POP_NOTREADY;
  416.                 if !#tostring(id:"") return false,_POP_NEEDID;

  417.                 return this.addCmd(_POP_DELE,id,onDele),this.loopMsg();
  418.         }
  419.         addCmd = function(pop_statue,id,callback_func,id_text,insert_mode){
  420.                 this.msgcount += 1;
  421.                 var cmd = this.buildCmd(pop_statue,concat(id,id_text))//id_text是给top xxx用的
  422.                 var task = {
  423.                                 ["cmd"]          = cmd;
  424.                                 ["callback"] = callback_func:this[concat("on",pop_statue)];
  425.                                 ["statue"]         = pop_statue;//pop_statue
  426.                                 ["id"]                 = id;
  427.                                 ["state"]         = null;        //服务器返回结果
  428.                                 ["msgId"]         = this.msgcount;
  429.                                 ["recvLength"] = 0;
  430.                         }
  431.                 if (pop_statue == _POP_LIST or pop_statue == _POP_UIDL ) && #id {
  432.                         task.endCRLF = true;       
  433.                 }
  434.                 if insert_mode {
  435.                         insert(this.Queue,task)
  436.                 }
  437.                 else {
  438.                         push(this.Queue,task);
  439.                 }
  440.                 return task.msgId;
  441.         }
  442.         getTask = function(id){
  443.                 return (id)?this.findTask(id):this.runTask;
  444.         }
  445.         findTask = function(id){
  446.                 for i = #this.Queue;1;-1{//反向搜索,避免出现删除的情况
  447.                         if id == this.Queue[i].msgId return this.Queue;
  448.                 }
  449.         }
  450.         loopMsg = function(clear = false){
  451.                 if clear{//注意清除时,当前的数据仍会继续跑,请注意时间
  452.                         this.Queue = {};
  453.                         return ;
  454.                 }
  455.                 if this.statue != _POP_CONN return false,this.login?_POP_PENDING:_POP_DISCONN;
  456.                 if !#this.Queue return false,"Queue is Empty";
  457.                  
  458.                 var task = remove(this.Queue);
  459.                 this.runTask = task;
  460.                 this.setStatue(task.statue);
  461.                 return this.socket.send(task.cmd);
  462.         }
  463.         setStatue = function(state){//为了统一调用定时器
  464.                 this.statue = state;
  465.                 if (state == _POP_CONN || stat == _POP_DISCONN){
  466.                         this.setTimer(2,0);
  467.                         this.setTimer(1,0)
  468.                 }
  469.                 else {
  470.                         this.setTimer(1,this.package_timeout);
  471.                         this.setTimer(2,this.statue_timeout);
  472.                 }
  473.         }
  474.         buildCmd = function(option,text){
  475.                 var cmd;
  476.                 select(option) {
  477.                         case _POP_LOGONUSER {
  478.                                 cmd =concat("USER ",text);
  479.                         }
  480.                         case _POP_LOGONPASS {
  481.                                 cmd = concat("PASS ",text);        
  482.                         }
  483.                         case _POP_STAT,_POP_QUIT,_POP_NOOP{
  484.                                 cmd = option;
  485.                         }
  486.                         case _POP_LIST,_POP_UIDL{
  487.                                 cmd = text?concat(option," ",text):option
  488.                         }
  489.                         case _POP_RETR,_POP_TOP,_POP_DELE{
  490.                                 cmd = concat(option," ",text)
  491.                         }
  492.                 }
  493.                 return concat(cmd,'\r\n');
  494.         }
  495.         changeSSLContext = function(vMode,certFile,keyFile,certPW,ca){
  496.                 var socket = this.socket;
  497.                 socket.sslCleanup();
  498.                 socket.sslSetupContext(vMode,certFile,keyFile,certPW,ca);
  499.         }
  500.         destroy = function(){
  501.                 if !this.connected return ;
  502.                 this.socket.stop();
  503.                 ::User32.SendMessage(this.timerHwnd,(0x400/*_WM_USER*/ + 10),0,0);
  504.                 this.connected = false;
  505.         }
  506. }


  507. namespace HP_POP3{
  508.         concat                = ..string.concat;
  509.         sub                        = ..string.sub;
  510.         pString                = ..raw.tostring;
  511.         push                = ..table.push;
  512.         insert                = ..table.insert;
  513.         remove                = ..table.remove;
  514.         join                = ..string.join;
  515.        
  516.         _POP_CONNTING        = "Connecting";
  517.         _POP_LOGONUSER        = "LogonUser";
  518.         _POP_LOGONPASS        = "LogonPass";
  519.         _POP_DISCONN        = "Disconnected";
  520.         _POP_CONN                = "Connected";
  521.         _POP_STAT                = "STAT";
  522.         _POP_LIST                = "LIST";
  523.         _POP_UIDL                = "UIDL";
  524.         _POP_RETR                = "RETR";
  525.         _POP_QUIT                = "QUIT";
  526.         _POP_NOTREADY        = "POP3 Server is Not Ready";
  527.         _POP_OK                        = "+OK";
  528.         _POP_ERR                = "-ERR"
  529.         _POP_NEEDID                = "LACK OF INDEX"
  530.         _POP_TOP                = "TOP"
  531.         _POP_DELE                = "DELE"
  532.         _POP_NOOP                = "NOOP"
  533.         _POP_PENDING        = "PENDING"
  534.        
  535.         _STATE_OK                = 0;
  536.         _STATE_ERR                = 1;
  537.         _STATE_DISCONN        = 2;
  538.         _STATE_TIMEOUT        = 3;
  539.        
  540.         _CRLF = '\r\n';
  541.         _POINTCRLF = concat(_CRLF,".",_CRLF);
  542.        
  543.         //------Fetch 状态-----------
  544.         _FR_OK                                = 0;        // 成功
  545.         _FR_LENGTH_TOO_LONG        = 1;        // 抓取长度过大
  546.         _FR_DATA_NOT_FOUND        = 2;        // 找不到 ConnID 对应的数据
  547.         //------回调时返回值------
  548.         _HR_OK                = 0;        // 成功
  549.         _HR_IGNORE        = 1;        // 忽略
  550.         _HR_ERROR        = 2;        // 错误

  551.         _SSL_VM_NONE                                        = 0x00;        // SSL_VERIFY_NONE
  552.         _SSL_VM_PEER                                        = 0x01;        // SSL_VERIFY_PEER
  553.         _SSL_VM_FAIL_IF_NO_PEER_CERT        = 0x02;        // SSL_VERIFY_FAIL_IF_NO_PEER_CERT
  554.         _SSL_VM_CLIENT_ONCE                        = 0x04;        // SSL_VERIFY_CLIENT_ONCE

  555.        
  556.         splitText = function(text,split =" "){
  557.                 if type(text) !=  type.string return null;
  558.                 var index = ..string.indexOf(text,split):#text+1;
  559.                 return sub(text,1,index-1),sub(text,index+#split,-1);
  560.         }
  561.         getPackState = function(pData,len){
  562.                 return pString(pData,1,4), pString(pData,len - 1,len), pString(pData,len - 4,len);
  563.         }
  564.         getHeadState = function(head){
  565.                 return (..string.trim(head) !==_POP_OK)?_STATE_ERR:_STATE_OK;
  566.         }
  567.         getHeadText = function(pData,len){
  568.                 var index = ..raw.indexOf(pData,len,'\r\n',4);
  569.                 return pString(pData,( pString(pData,5,5) == ' ')?6:5,index -1),( index + 1 < len )?(index+2):0;
  570.         }
  571. }


  572. /**intellisense()
  573. HP_POP3() = !HP_POP3.
  574. HP_POP3(.(server,user,pw,ssl,port,vMode,certFile,keyFile,certPW,ca)) = 创建异步POP3(SSL)邮件客户端,客户端基于HPSocket.(SSL).PullClient模式\nssl参数是True时启用SSL模式,port默认为110(995),vMode等参数参考sslSetupContext
  575. end intellisense**/

  576. /**intellisense(!HP_POP3)
  577. socket = hpsocket句柄
  578. connect(.(user,pw,port,onLogin,onConn) = 连接服务器,五个参数均可省略,后两个参数是重新指定回调函数
  579. stat(.(onSTAT) = 发送STAT指令,onSTAT参数重新指定回调函数,可省略
  580. quit(.(onQUIT) = 发送QUIT指令,onQUIT参数重新指定回调函数,可省略
  581. list(.(id,onLIST) = 发送LIST指令,id指邮件索引,onLIST参数指定回调函数,两个参数可省略
  582. uidl(.(id,onUIDL) = 发送UIDL指令,id指邮件索引,onUIDL参数指定回调函数,两个参数可省略
  583. retr(.(id,onRETR) = 发送LIST指令,id指邮件索引,onRETR参数指定回调函数,参数可省略
  584. dele(.(id,onDELE) = 发送DELE指令,id指邮件索引,onDELE参数指定回调函数,参数可省略
  585. top(.(id,num,onTOP) = 发送LIST指令,id指邮件索引,num指返回头行的数量,onTOP参数指定回调函数,后两个参数可省略
  586. changeSSLContext(.(vMode,certFile,keyFile,certPW,ca) = 更改SSL环境参数
  587. setTimeOut(.(pack_timeout,data_timeout) = 设置超时检查时间,pack是数据包间隔超时,data是当前状态接收总超时
  588. onConn  = @.onConn = function(connId){
  589.     __/*连接后触发,connId为hpsocket的活动Id*/
  590. }
  591. onLogin = @.onLogin = function(err,text){
  592.         __/*获得登录信息*/
  593. }
  594. onSTAT = @.onSTAT = function(err,num,size,errText){
  595.         __/*获得STAT信息,num、size为邮件总数量、大小,errText是服务器返回的错误信息*/
  596. }
  597. onQUIT = @.onQUIT = function(err,text){
  598.         __/*退出邮箱信息,text是服务器返回信息*/
  599. }
  600. onLIST = @.onLIST = function(err,num,size,content){
  601.         __/*获得LIST信息,num,size为邮件总数量、大小,部分服务器不返回,content是邮件id和length的集合,错误时是错误信息*/
  602. }
  603. onUIDL = @.onUIDL = function(err,num,emptyText,content){
  604.         __/*获得LIST信息,num为邮件总数量,部分服务器不返回,content是邮件id和key的集合,错误时是错误信息*/
  605. }
  606. onRETR = @.onRETR = function(err,id,length,content){
  607.         __/*获得邮件内容,id 是邮件索引,length 总长度,content 是邮件内容,错误时是错误信息*/
  608. }
  609. onDELE = @.onDELE = function(err,id,text){
  610.         __/*获得删除结果, id 是邮件索引,text是服务器返回信息*/
  611. }
  612. onTOP = @.onTOP = function(err,id,length,content){
  613.         _/*获得邮件头,id 是邮件索引,length 总长度,content 是邮件头,错误时是错误信息*/
  614. }
  615. onDebug = @.onDebug = function(pop_statue,task,pData,len){
  616.         _/*当出现错误消息时,会触发此事件*/
  617. }
  618. end intellisense**/
  619. //作者:republican/ZGMF-X-20A
复制代码
回复

使用道具 举报

2

主题

9

帖子

145

积分

一级会员

Rank: 2

积分
145
 楼主| 发表于 2018-8-11 00:47:22 | 显示全部楼层
demo源码:
  1. import win.ui;
  2. import HP_POP3;
  3. import console;
  4. /*DSG{{*/
  5. var winform = win.form(text="aardio form";right=759;bottom=469;parent=...)
  6. winform.add(
  7. button={cls="button";text="连接";left=63;top=40;right=158;bottom=69;z=1};
  8. button2={cls="button";text="STAT";left=170;top=41;right=270;bottom=71;z=2};
  9. button3={cls="button";text="LIST";left=66;top=93;right=149;bottom=125;z=3};
  10. button4={cls="button";text="UIDL";left=172;top=94;right=265;bottom=125;z=4};
  11. button5={cls="button";text="RETR";left=69;top=153;right=154;bottom=187;z=5};
  12. button6={cls="button";text="TOP";left=171;top=154;right=267;bottom=188;z=6};
  13. button7={cls="button";text="断开";left=71;top=217;right=158;bottom=257;z=9};
  14. button8={cls="button";text="DELE";left=434;top=96;right=519;bottom=121;z=10};
  15. edit={cls="edit";left=297;top=104;right=387;bottom=124;edge=1;multiline=1;z=7};
  16. edit2={cls="edit";left=300;top=166;right=392;bottom=187;edge=1;multiline=1;z=8}
  17. )
  18. /*}}*/

  19. var pop3_client = HP_POP3("服务器地址","用户名","密码");

  20. pop3_client.onLogin = function(err,text){
  21.         console.log(err,text)
  22. }

  23. pop3_client.onQUIT = function(err,text){
  24.         console.log(err,text)
  25. }

  26. pop3_client.onSTAT = function(err,num,size,errText){
  27.         console.log(err,num,size,errText)
  28. }

  29. pop3_client.onLIST = function(err,num,size,content){
  30.         console.log(err,num,size);
  31.         console.dump(content);
  32. }

  33. pop3_client.onUIDL = function(err,num,empty,content){
  34.         console.log(err,num)
  35.         console.dump(content);
  36. }

  37. pop3_client.onTOP = function(err,id,len,content){
  38.         console.log(err,id,len)
  39.         console.log(content)
  40. }

  41. pop3_client.onRETR = function(err,id,len,content){
  42.         console.log('RETR',err,id,len)
  43.         var file = io.open(string.concat("/log/emial-",id,".eml"),"wb+");
  44.         file.write(content);
  45.         file.close();
  46. }


  47. winform.button.oncommand = function(id,event){//连接
  48.         console.log(pop3_client.connect());
  49. }

  50. winform.button7.oncommand = function(id,event){//退出
  51.         pop3_client.quit();
  52. }

  53. winform.button2.oncommand = function(id,event){
  54.         pop3_client.stat();
  55. }

  56. winform.button3.oncommand = function(id,event){
  57.         pop3_client.list(winform.edit.text);
  58. }

  59. winform.button4.oncommand = function(id,event){
  60.         pop3_client.uidl(winform.edit.text);
  61. }

  62. winform.button6.oncommand = function(id,event){
  63.         pop3_client.top(winform.edit2.text);
  64. }

  65. winform.button5.oncommand = function(id,event){
  66.         pop3_client.retr(winform.edit2.text);
  67. }

  68. winform.enableDpiScaling();
  69. winform.show();

  70. win.loopMessage();
  71. return winform;
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-10-22 06:05 , Processed in 0.062500 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表