如何在我的代码中刷新套接字

时间:2012-04-25 14:45:39

标签: javascript sockets firefox-addon firefox-addon-sdk

我正在通过FF加载项的套接字写入java服务器。我写了几个请求,服务器似乎一个接一个地处理它们。相反,来自服务器的响应全部同时处理。

我已经尝试在服务器中刷出输出流,但它什么也没做。我不明白发生了什么。

感谢您的帮助,谢谢。

EDIT1:可能是附加组件(客户端)没有刷新输入流,这可能吗?我在java服务器中使用了out.println所以'\ n'必须刷新它的输出流,而net库使用write.flush(),但我没有看到任何其他的输入刷新。

EDIT2:这是我的代码:

exports.main = function() {
    try  {
        // At first, we need a nsISocketTransportService
        var transportService =  
            Cc["@mozilla.org/network/socket-transport-service;1"]
            .getService(Ci.nsISocketTransportService);  

        // Try to connect to localhost:2222
        var transport = transportService.createTransport(null, 0, "localhost", 6666, null);  

        var stream = transport.openInputStream(Ci.nsITransport.OPEN_UNBUFFERED,null,null); 
        var instream = Cc["@mozilla.org/scriptableinputstream;1"]
            .createInstance(Ci.nsIScriptableInputStream); 

        // Initialize
        instream.init(stream);
        var outstream = transport.openOutputStream(0, 0, 0);



        var dataListener = { 
            onStartRequest: function(request, context){},

            onStopRequest: function(request, context, status){
                instream.close();
                outstream.close();
            }, 

            onDataAvailable: function(request, context, inputStream, offset, count) { 
                var data = instream.read(count); 
                console.log(data);             
            }, 
        };

        var pump = Cc["@mozilla.org/network/input-stream-pump;1"]
                .createInstance(Ci.nsIInputStreamPump); 
        pump.init(stream, -1, -1, 0, 0, false); 
        pump.asyncRead(dataListener, null); 

        // Write data
        console.log("hi1");
        var outputData = "hi1\n";
        outstream.write(outputData, outputData.length);

        // Write data
        console.log("hi2");
        var outputData = "hi2\n";
        outstream.write(outputData, outputData.length);

    } catch (e){ 
        console.log("Error" + e.result + ": " + e.message); 
        return e; 
    } return null;
};

所以,当我运行它时,我得到:

Client > hi1
Client > hi2
Server > bye1
Server > bye2

它应该是:

Client > hi1
Server > bye1
Client > hi2
Server > bye2

2 个答案:

答案 0 :(得分:0)

TCP是一种流协议,因此您会收到一个字节流。如果你想要数据包,你必须通过TCP实现自己的协议才能分离它们。这个主题在互联网上被广泛报道。

修改

这是套接字编程中常见的陷阱。大多数人一开始并不了解TCP套接字是流,而不是消息队列。

我的意思是,在插座一端的“发送”调用与另一端的“接收”不一致。底层可以决定对随意发送的字节进行分组或拆分。

所以你可以这样:

  • 客户端发送“ABCD”
  • 客户端发送“EFGH”
  • 服务器收到“AB”
  • 服务器收到“CDEF”
  • 服务器收到“GH”

这是一个流,而不是一个消息队列。把它想象成你正在阅读的无限文件。

因此,如果您想从文件中读取字符串,则需要一些方法来分隔它们。它可以是分隔符,也可以按字符串的长度或其他任何方式为字符串添加前缀。

答案 1 :(得分:0)

您正在同步写入输出流,这意味着在您执行此操作时不能运行其他JavaScript代码。因此,在写入时从服务器接收任何内容是不可能的,传入的数据只是放入缓冲区。

另一个问题是您正在发送下一个字符串而不等待服务器的响应。通常,您可以在服务器响应到来之前发送它们。您可能只想在收到对前一个字符串的响应时才发送下一个字符串。

你可能想要使用像这样的发送功能:

Components.utils.import("resource://gre/modules/NetUtil.jsm");

var toSend = ["hi1\n", "hi2\n"];

function sendNextString(outstream)
{
  if (!toSend.length)
    return;  // Nothing left to send

  var outputData = toSend.shift();
  console.log(outputData);
  var instream = Components.classes["@mozilla.org/io/string-input-stream;1"]
                           .createInstance(Components.interfaces.nsIStringInputStream);
  instream.setData(outputData, outputData.length);

  NetUtil.asyncCopy(instream, outstream);
}

您可以在sendNextString(outstream)之后以及pump.asyncRead()之后在代码中致电onDataAvailable

PS:据我所知,刷新流是而不是这里的问题 - 你正在使用非缓冲流。