如何在Node.js中实现读/写客户端(如POP3客户端)

问题描述:

我并不十分精通node.js的艺术,所以我不知道如何去做这件事:我想编写一个客户端,该客户端可以连接到POP3服务器并写入服务器,并对服务器发回的信息做出反应。如何在Node.js中实现读/写客户端(如POP3客户端)

  1. 到服务器的开放连接
  2. 读取服务器欢迎
  3. 发送 “USER [email protected]
  4. 检查 “接受+ OK用户”
  5. 发送 “PASS输入mypassword”
  6. 检查“+ OK通行证”

如果服务器回答任何问题,但确定,触发一个错误或事件。

我到目前为止有:

var net = require('net') 
    , sys = require('sys') 
; 

conn = net.createConnection(110, 'mail.somehost.com'); 
conn.setEncoding("utf8"); 
//1. Open Connection 
conn.on('connect', function() { 
    //2. Read welcome 
    conn.once('data', function(data) { 
     conn.pause(); 
     console.log('Server Welcome: ' + data); 
     //4. Prepare to get response from server 
     conn.once('data', function(data) { 
      console.log('USER Response: ' + data); 
     }); 
     //3. Send USER 
     conn.write('USER [email protected]' + "\n"); 
     conn.resume(); 
    }) 

}); 

请问conn.pause,处理的回报,conn.once,conn.write,conn.resume序列适用于所有的互动?

更新

如前所述,你应该用下面的办法去:

  1. 写了协议的基本语法分析器,你可能最终得到data仅具有前5个字节一行,你需要处理这个没有吨的重复
  2. 解析器缓冲数据并将其分派到不同的事件
  3. 这将是相当容易的添加pause功能解析器,如果你真的需要使用
  4. 调度模型结合的状态变量您的代码将:

    A.看路除渣
    B.要容易得多维护
    C.可以,例如,发送USER Response然后让OK处理方法决定什么它基于当前状态

  5. 这将总体减少代码的重复。另外你现在正在做什么被称为箭编程(所有IFS /回调形成一个箭头)

老答案

更多的数据服务器等待进来,简单地放,你需要结束你发送的行CLRF又名。 \r\n

conn.write('USER [email protected]\r\n'); 

猜你应该给规范读:
http://tools.ietf.org/html/rfc1939

此外,您.once方法将很快,变得非常复杂的维护。我将使用正常的.on事件处理并为通信进程设置状态。

var state = 'CONNECT'; 
conn.on('connect', function() { 
    conn.on('data', function(data) { 
     // actually you should make sure that you got the COMPLETE message here 
     // it may be the case that you only got half of it so check for CLRF 
     // you should also buffer stuff after an incoming CLRF 
     // best thing would be that you write a parser first that then dispatches the messages 
     // to specific handlers 

     switch (state) { 
      case 'CONNECT': 
       // blabla 
       state = 'GETRESPONSE'; 
       break; 

      case 'GETRESPONSE': 
       // response 
       break; 

      case default: 
       break; 
     } 
    }) 
}); 

当然你怎么正是实现这个是留给你,你也可以同样的当前状态映射到功能表/方法,它获得这些数据,并用它做什么。

+0

Thanx为您的答案。我在发布后不久更新了该问题,因为我看到我没有发送CRLF。我主要关心的是如何处理返回的数据。 – Jrgns 2010-12-15 12:14:57