【问题标题】:Make TCP socket bi-directional in Thunderbird extension?在 Thunderbird 扩展中使 TCP 套接字双向?
【发布时间】:2017-05-14 20:00:14
【问题描述】:

在 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_BLOCKINGOPEN_UNBUFFERED 标志 => 无效。
  • 在循环中检查 istream.available() 而不是使用 cstream => 即使 TCP 连接的另一端已发送数据,也将始终返回 0。

【问题讨论】:

    标签: thunderbird-addon


    【解决方案1】:

    我分析了 Thunderbird 的源代码:

    如果设置了OPEN_UNBUFFERED 而未设置OPEN_BLOCKING 则显然openInputStream 使用了一个相当“简单”的实现,而其他三种组合使用了一个相当复杂的实现。

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

    另一个页面说 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();
    

    【讨论】:

      猜你喜欢
      • 2012-11-10
      • 2013-12-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多