2017-11-20 4 views
0

QtからRにデータを送信しようとしています。私はQtNetworkモジュールを初めて使用しており、比較的新しいQtを使用しています。 QIODeviceが読み書きのためにデータをどのようにエンコードするかを理解しようとしています。QtcpSocketをRから読み取る方法

IはFortune Server Exampleを実行してRで次のコードとそれに接続する場合:

connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10) 
readBin(connection, what="raw", n = 1000) 

以下生進ベクトルが

00 00 00 56 00 59 00 6f 00 75 00 20 00 77 00 69 00 6c 00 6c 00 20 00 66 00 65 00 65 00 6c 00 20 00 68 00 75 00 6e 00 67 00 72 00 79 00 20 00 61 00 67 00 61 00 69 00 6e 00 20 00 69 00 6e 00 20 00 61 00 6e 00 6f 00 74 00 68 00 65 00 72 00 20 00 68 00 6f 00 75 00 72 00 2e 

は、最初の5つのバイトを削除し、残りのすべて返されますヌル文字を変換してcharに変換すると、次のようになります。

"You will feel hungry again in another hour." 

だからwh私が知りたいのは、財産の一部ではない文字はどこから来るのでしょうか? 4番目のバイトは、6番目のバイトから最後までのメッセージのバイト長であると思われ、残りの「不運」文字はすべてnullです。

私はQByteArrayがヌル文字で各バイトを終了し、QByteArrayがQTcpSocketによって書き込まれる前にQBufferに変換されることを読みましたが、ここで何が起きていますか? QBufferはメッセージの長さを追加します(ただし、他の4バイトの長さ)、QByteArrayの1バイトごとにヌル文字が追加されますか?また、最後のバイトはnullではありません(readBin操作で消費されましたか/ readBinはメッセージの終了位置を知っていましたか)。

これはソケットにデータを書き込む唯一の方法ですか? double型の値を送信したいのであれば、QByteArrayに変換する必要があります。ソケットを介してデータを送信するテキスト以外の方法はありませんか?

啓発は大いにありがとう!

編集:

ありがとうございました!完全のために、ここであなたは、あなたはそれがQDataStreamが終わっ運勢(QString複数可)をシリアル化するために使用していることがわかりますフォーチュンサーバー例が実装されている方法を見てみた場合は、R

connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10) 

# Read first 32 bits, which contains the size of the string in bytes 
len.raw <- readBin(connection, what="raw", n = 4) 

# convert to integer 
len <- strtoi(paste(c("0x",len.raw),collapse="")) 

# Read raw message 
msg.raw <- readBin(connection, what="raw", n = len) 

# convert to char using UTF-16BE 
msg <- iconv(list(msg.raw),from="UTF-16BE") 

close(connection) 

cat(msg) 

答えて

0

内の文字列をデコードする方法をありますソケットは:「?QDataStreamシリアル化にどのようQString S」

QByteArray block; 
QDataStream out(&block, QIODevice::WriteOnly); 
out.setVersion(QDataStream::Qt_4_0); 

out << fortunes.at(qrand() % fortunes.size()); 

ので、質問がに低減され、これはドキュメントのページについてserializing Qt data typesで広範囲に答えています。文字列がnullの場合

  • :あなたはQStringのシリアライズはこのようになっていることを見ることができますから0xFFFFFFFF(quint32)
  • そうでない場合:内のデータに続くバイトの文字列の長さ(quint32は) UTF-16

そして、これはあなたがあなたの質問に見ているかを正確にあります。最初の4バイトは文字列の長さ(バイト数)で、UTF-16エンコーディングを使用しているため、後で表示される「null」が表示されます。


これはソケットにデータを書き込むための唯一の方法ですか? double型の値を送信したいのであれば、QByteArrayに変換する必要があります。ソケットを介してデータを送信するテキスト以外の方法はありませんか?

あなたは好きなようにserialization formatを使用できます。 QDataStreamは、ほとんどのQtデータ型をそのまま使用できるので、Qtで広く使用されています。これはQByteArrayを使用することとは無関係で、QDataStreamを直接ソケットに書き込ませることができます。 QDataStreamは、実際にはバイナリ形式(非テキスト形式)です。人間が読める形式のテキストが必要な場合はJSONを使用できます。

しかし、あなたはQDataStreamを使用してRにはQtからデータを送信することを目指していた場合、あなたはR.のためのあなたのQDataStreamデシリアライザを記述する必要があります私はの代わりにC++とR(での実装を持っているいくつかの一般的なデータのシリアル化を使用することをお勧めします車輪の再発明)。私はJSONがこの基準を満たしていると信じています。バイナリ形式を使用したい場合、msgpackは多種のプログラミング言語(RやC++を含む)をサポートしているので興味深いかもしれません。

+0

ありがとう、これは大きな助けです。特にあなたが探しているものがわからない私の場合のように。 – byrongibby

関連する問題