0

ソケットを介して FF アドオンから Java サーバーに書き込みを行っています。いくつかのリクエストを書きますが、サーバーはそれらを 1 つずつ処理しているようです。対照的に、サーバーからの応答はすべて同時に処理されます。

サーバーで出力ストリームをフラッシュしようとしましたが、何もしません。何が起こっているのかわかりません。

助けていただければ幸いです、ありがとう。

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 ソケットがメッセージ キューではなくストリームであることを理解していません。

つまり、ソケットの一方の端での「送信」への 1 回の呼び出しが、もう一方の端での1 回の「受信」に対応するとは限りません。下位層は、送信されたバイトを自由にグループ化または分割することを決定できます。

したがって、次のようなものを使用できます。

  • クライアントは「ABCD」を送信します
  • クライアントは「EFGH」を送信します
  • サーバーは「AB」を受け取ります
  • サーバーは「CDEF」を受け取ります
  • サーバーが「GH」を受信

これはストリームであり、メッセージ キューではありません。読み込んでいる無限のファイルと考えてください。

そのため、ファイルから文字列を読み取りたい場合は、文字列を分離する何らかの方法が必要です。区切り文字にすることも、文字列の長さなどを文字列のプレフィックスにすることもできます。

于 2012-04-25T16:39:38.753 に答える
0

出力ストリームに同期的に書き込みます。つまり、書き込み中に他の JavaScript コードを実行することはできません。したがって、書き込み中にサーバーから何かを受信することは不可能であり、受信データは単にバッファーに入れられます。

もう 1 つの問題は、サーバーからの応答を待たずに次の文字列を送信していることです。通常、サーバーの応答が到着する前に両方を送信できます。おそらく、前の文字列に対する応答を受信したときにのみ、次の文字列を送信する必要があります。

おそらく、次のような send 関数を使用する必要があります。

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 に答える