QTcpSocket: чтение и запись
Я знаю, что некоторые подобные вопросы, возможно, уже задавались, но ответы на те, которые я нашел, охватывали очень специфические проблемы, и я до сих пор не понял их.
В моей программе я создаю QObject (называемый QPeer), который использует QTcpSocket для связи с другим таким объектом по сети. QPeer имеет слот, который принимает QByteArray с данными (sendData(QByteArray)
). Все содержимое этого массива считается одним «сообщением» и записывается в сокет. Я хочу сделать следующее: каждый раз, когда пишется сообщение, я хочу, чтобы получающий QPeer испускал свой сигналdataReceived(QByteArray)
ровно один раз, тот QByteArray, содержащий все сообщение. (ПРИМЕЧАНИЕ: все сигналы / слоты, как частные, соединяющие QPeer с его сокетом, так и публичные, такие какsendData(QByteArray)
сериализуются с помощьюQt::QueuedConnection
при необходимости.)
Я использую сигналQTcpSocket::readyRead()
для асинхронного чтения из сокета. Теперь я знаю, что не могу просто позвонитьQTcpSocket::write()
один раз в sendData, а затем предположим, что для каждой записи, которую я делаю, QTcpSocket на другой стороне генерирует ровно один сигнал readyRead. И что же мне делать?
Это моя идея, пожалуйста, скажите мне, если это будет работать:
ПИШУ:
void QPeer::sendData(QByteArray data)
{
// TODO: write data.size() as raw int of exactly 4 bytes to socket
const char *bytes = data.constData();
int bytesWritten = 0;
while (bytesWritten < data.size())
bytesWritten += _socket->write(bytes + bytesWritten);
}
ЧТЕНИЕ:
теперь я хочу функцию чтения (подключен кQTcpSocket::readyRead()
) использовать заголовок (4 байта int, определяющий длину сообщения), а затем прочитать это количество байтов; затем отправлять данные, полученные именно с этими байтами. У меня серьезные проблемы с попытками сделать это.Например: что делать, если выдается readyRead, и я могу прочитать заголовок сообщения, но не указанное количество байтов? Или что, если заголовок был получен только частично?
1. Как правильно записать заголовок (4 байта int) в сокет?
2. Как правильно реализовать функцию чтения, чтобы она выполняла то, что я хочу?
Любые советы приветствуются. Спасибо!