我正在通过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
答案 0 :(得分:0)
TCP是一种流协议,因此您会收到一个字节流。如果你想要数据包,你必须通过TCP实现自己的协议才能分离它们。这个主题在互联网上被广泛报道。
修改强>
这是套接字编程中常见的陷阱。大多数人一开始并不了解TCP套接字是流,而不是消息队列。
我的意思是,在插座一端的“发送”调用与另一端的“接收”不一致。底层可以决定对随意发送的字节进行分组或拆分。
所以你可以这样:
这是一个流,而不是一个消息队列。把它想象成你正在阅读的无限文件。
因此,如果您想从文件中读取字符串,则需要一些方法来分隔它们。它可以是分隔符,也可以按字符串的长度或其他任何方式为字符串添加前缀。
答案 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:据我所知,刷新流是而不是这里的问题 - 你正在使用非缓冲流。