0

我正在通过从 FF 附加组件到 Java 服务器的套接字写入。我写了几个请求,服务器似乎一个接一个地处理它们。相反,来自服务器的响应是同时处理的。

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

我很感激任何帮助,谢谢。

EDIT1:可能是附加组件(客户端)没有刷新输入流,这可能吗?我在java服务器中使用out.println,所以'\n'必须刷新它的输出流并且网络库使用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
4

2 回答 2

0

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

编辑

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

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

所以你可以有这样的东西:

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

这是一个流,而不是消息队列。将其视为您正在读取的无限文件。

所以,如果你想从文件中读取字符串,你需要一些方法来分离它们。它可以是分隔符,或者您可以在字符串前面加上字符串的长度,或者其他。

于 2012-04-25T16:39:38.753 回答
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:据我所知,刷新流不是这里的问题-您使用的是非缓冲流。

于 2012-04-25T19:06:57.500 回答