ソケット上で送信されるバイナリデータの簡単なテストを設定しています。バッファを渡して渡すときにnodejsソケットが奇妙に動作する
送信側では、呼び出しに渡された引数の数を単純にエンコードし、次に各引数について、その引数の長さをエンコードします。これは私に様々なバイナリデータを送信してテストするために迅速かつ簡単な方法を提供します:受信側では
var client = new net.Socket()
client.connect(9999, host, function() {
console.log("Connected")
// convert argument list into length delimited parameters
var i,args = process.argv.length-3
var buf = new Buffer(4)
buf.writeInt32LE(args,0)
client.write(buf)
console.log("sending "+args+" args")
for (i=3;i<args+3;i++) {
console.log("["+(i-3)+"] "+process.argv[i].length)
buf.writeInt32LE(process.argv[i].length)
client.write(buf)
}
client.end()
})
私は余分な引数の数が、その後、各引数のために、私はその引数の長さを抽出し、全部を印刷します。私は小さなステートマシンを使って、私が読んでいる場所を把握しています。私は見てい
var server = net.createServer(function(x) {
console.log("connected")
var state=0,args,argn
x.on("readable",function() {
switch (state) {
case 0:
var n = x.read(4)
console.log("[0]"); console.dir(n)
if (n === null) return
args=n.readInt32LE(0)
console.log(args+" arguments")
state = 1 ; argn = 0
break
case 1:
var n = x.read(4)
console.log("[1]"); console.dir(n)
if (n === null) return
console.log("argument "+argn+" has "+n.readInt32LE(0)+" bytes")
if (++argn > args) {
console.log("end of arguments")
state = 0
}
break
default:
console.log("state="+state+", now what?")
}
})
x.on("close",function() { console.log("closed") })
x.on("end",function() { console.log("ended") })
server.listen({port:9999})
問題は、私は最後の二つの引数の長さ(32ビット整数)を受けるように見えることはありませんということです。私は送信側で1つまたは2つの追加の整数を送信してみましたが、違いがあるかどうかを確認しましたが、そうではありません。 の可読性のあるコールバックは、これまで想定されていた回数だけ呼び出されることはありません。例えば
、クライアント側で私が起動する場合:
node tcptest.js tx "Hello world" 12345 AAA 9
クライアント側の出力は次のようになります。
sending
Connected
sending 4 args
[0] 10
[1] 5
[2] 3
[3] 1
Connection closed
しかし、サーバ側で、私が見るすべては次のとおりです。
receiving
connected
[0]
Buffer [ 4, 0, 0, 0 ]
4 arguments
[1]
Buffer [ 10, 0, 0, 0 ]
argument 0 has 10 bytes
[1]
Buffer [ 5, 0, 0, 0 ]
argument 1 has 5 bytes
socket ended
socket closed
私はbuf
オブジェクトを再利用しようとしませんでしたが、しばらく働いていましたが、間欠的にもう一度失敗する。それはしばらくの間、再び仕事を始めたとき
...
for (i=3;i<args+3;i++) {
buf = new Buffer(4)
console.log("["+(i-3)+"] "+process.argv[i].length)
...
は、私は多分書くために渡すために再利用されることからバッファを許可されていない文書化されていない何かがあったと思ったが、今私は知りません。バッファをまったく使用しない場合ソケットにstdinをパイプするとうまくいきますが、このようなバイナリデータを構築しようとすると必ず受け取られるわけではありません。
私は間違っていますか?
更新: サーバー側でread()
を呼び出してバイト数を指定するのではなく、受信したすべてのデータが表示されます。私は何が起きているのだろうと思うのは、利用可能なバイト数よりも少ないバイト数を読み込んだ場合、私は追加のコールバックを取得しないということです。
あなただけのソケット 'のようなものをやってみました。 pipe(decrypter).pipe(process.stdout) 'サーバー上で? – idbehold
@ idbeholdええ、それは(クライアントを除いて)作品に似ています。私は質問を書き直しました...暗号化とはまったく関係がなく、バッファオブジェクトを再利用することとは何も関係がないようです – Michael