2017-05-14 32 views
0

在雷鸟扩展我用下面的代码来等待进入的TCP连接:在Thunderbird扩展中制作双向TCP套接字?

function MyExtension_OnNewConnection(srvSock, newSock) 
{ 
    var block = Components.interfaces.nsITransport.OPEN_BLOCKING | 
     Components.interfaces.nsITransport.OPEN_UNBUFFERED; 
    var istream = newSock.openInputStream(block, 0, 0); 
    var ostream = newSock.openOutputStream(block, 0, 0); 

    var cstream = Components. 
     classes["@mozilla.org/scriptableinputstream;1"]. 
     createInstance(Components.interfaces.nsIScriptableInputStream); 
    cstream.init(istream); 
    var y = cstream.read(1); 
    cstream.close(); 
    if(y == "") 
    { 
     var y = "The socket is Tx-Only!\r\n"; 
     ostream.write(y, y.length); 
    } 

    istream.close(); 
    ostream.close(); 
} 

... 

waitSocket = Components.classes["@mozilla.org/network/server-socket;1"]. 
     createInstance(Components.interfaces.nsIServerSocket); 
waitSocket.init(-1, false, -1); 
waitSocket.asyncListen({ 
    onSocketAccepted: MyExtension_OnNewConnection, 
    onStopListening: function(socket, status) {} 
}); 

根据文档cstream.read()当TCP套接字关闭只能返回一个空字符串。

ostream.write()函数将发送一些数据,但只有在TCP套接字未关闭的情况下才可能发送。

但是cstream.read()返回一个空字符串,ostream.write()发送一些数据,TCP连接的另一端接收到字符串!

这意味着TCP连接是单向(从一开始!)。

问题:

  • 为什么?
  • 如何才能使TCP连接成双向的,以便我可以接收数据?

我已经尝试过:

  • 不使用OPEN_BLOCKING也不OPEN_UNBUFFERED标志=>无影响。
  • 在循环中检查istream.available()而不是使用cstream =>即使数据已由TCP连接的另一端发送,也将始终返回0。

回答

0

我分析雷鸟的源代码:

显然openInputStream使用非常“简单”的实施,如果OPEN_UNBUFFERED设置和OPEN_BLOCKING而相当复杂的执行用于其他三个组合未设置。

简单的实现工作完美,但阻止套接字访问是不可能的。

另一页说的Javascript功能应该以非阻塞的方式编写,所以我决定用下面的实现:

function CalledOnTimer() 
{ 
    try 
    { 
     while(true) 
     { 
      data = cstream.read(NumberOfBytes); 
      if(data == "") 
      { 
       /* Socket has been closed */ 
       cstream.close(); 
       istream.close(); 
       ostream.close(); 
       ... 
       return; 
      } 
      /* Process the data */ 
      ... 
     } 
    } 
    catch(dummy) 
    { 
     /* Currently no (more) data on the socket */ 
     restartTheTimer(); 
    } 
} 

... 
var istream = newSock.openInputStream(
    Components.interfaces.nsITransport.OPEN_UNBUFFERED, 0, 0); 
... 
cstream.init(istream); 
... 
startTheTimer();