2017-05-14 34 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();