送金の受け取りに問題があります。
QTcpSocket-> readAll()は、送信時に十分なバイトを読み取りません。15kバイトを送信すると、その一部のみが読み取られ、何も実行されません。私は何が間違っているのですか?
QByteArray array;
array = socket->readAll(); //just reads some part, not fully.
なぜこれが起こるのですか?
送金の受け取りに問題があります。
QTcpSocket-> readAll()は、送信時に十分なバイトを読み取りません。15kバイトを送信すると、その一部のみが読み取られ、何も実行されません。私は何が間違っているのですか?
QByteArray array;
array = socket->readAll(); //just reads some part, not fully.
なぜこれが起こるのですか?
を呼び出したときに、ソケットがまだすべてのデータを受信していない可能性がありますreadAll()
。これは、TCP通信が小さなパケットで発生するためです(多くの場合、それぞれに約1KBのデータがあります)。これらのパケットは、通信回線のもう一方の端がバイトを書き込むストリームを構成します。受信側で組み立てる必要があります。それらをどのように組み立てるかは、プロトコルで定義する必要があります。
この問題を解決するには、予想されるすべてのデータを待ってから組み立てる必要があります。(プロトコルによっては)読み取らない限り、予想されるデータ量がわからない場合があります。
「改行までのすべてがメッセージと呼ばれるものである」というプロトコルを実装するとします。今、あなたはそのようなメッセージを受け取りたいです。QByteArray
これは、改行が発生するまでターゲットバッファ(のような)を連続して読み取り、追加することによって行われます。ただし、別のことがあります。2番目のメッセージを予期する場合、TCPストリームの最初のメッセージの直後になる可能性があるため、最初のメッセージの終わりだけでなく、2番目のメッセージの始まりも読み取るだけです。これを覚えておいてください。
信号スロット接続を処理しない場合は、次のような改行で区切られたメッセージの同期レシーバーを作成できます。
QByteArray array;
while(!array.contains('\n')) {
socket->waitForReadyRead();
array += socket->readAll();
}
int bytes = array.indexOf('\n') + 1; // Find the end of message
QByteArray message = array.left(bytes); // Cut the message
array = array.mid(bytes); // Keep the data read too early
processMessage(message);
を扱うときQTcpSocket::readyRead()
、あなたは同じようなことをすることができます。
void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
array += socket->readAll();
if(array.contains('\n')) {
int bytes = array.indexOf('\n') + 1; // Find the end of message
QByteArray message = array.left(bytes); // Cut the message
array = array.mid(bytes); // Keep the data read too early
processMessage(message);
socketReadyRead(); // re-call myself to process more
}
}
1つのTCP接続を介して送信されたすべてを(ピアによって閉じられるまで)読み取りたい場合は、このイベントをブロックする方法で待機するか、適切な信号に接続されたスロットでデータを処理できますQTcpSocket::disconnected
。
ブロッキング:
socket->waitForDisconnected();
QByteArray array = socket->readAll();
ノンブロッキング(スロットを使用した信号の処理):
void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
array += socket->readAll();
// Do NOT process yet!
}
void MyClass::socketDisconnected() // connected to QTcpSocket::disconnected() signal
{
processMessage(array);
}
代替のノンブロッキングソリューション(基本的に同じ):
// You don't have to connect to QTcpSocket::readyRead() signal in this case
void MyClass::socketDisconnected()
{
processMessage(socket->readAll());
}