我想连接到监听服务器并传输一些数据。我查看了可用的示例,但它们似乎有额外的功能,对我来说似乎没有什么帮助(即连接,财富等)。这是我到目前为止的代码:
QTcpSocket t;
t.connectToHost("127.0.0.1", 9000);
假设服务器正在监听并且健壮,我需要实现什么来发送数据类型为QByteArray
的数据变量?
答案 0 :(得分:23)
void MainWindow::connectTcp()
{
QByteArray data; // <-- fill with data
_pSocket = new QTcpSocket( this ); // <-- needs to be a member variable: QTcpSocket * _pSocket;
connect( _pSocket, SIGNAL(readyRead()), SLOT(readTcpData()) );
_pSocket->connectToHost("127.0.0.1", 9000);
if( _pSocket->waitForConnected() ) {
_pSocket->write( data );
}
}
void MainWindow::readTcpData()
{
QByteArray data = pSocket->readAll();
}
请注意,对于从TcpSocket读取,您可能会收到多个传输中的数据,即。当服务器发送字符串“123456”时,您可能会收到“123”和“456”。您有责任检查传输是否完整。不幸的是,这几乎总会导致你的班级有状态:班级必须记住它所期望的传输,是否已经启动以及是否已经完成。到目前为止,我还没有想出一个优雅的方法。
答案 1 :(得分:5)
在我的情况下,我正在阅读xml数据,有时我不会在一个数据包中得到所有数据。 这是一个优雅的解决方案。 WaitForReadyRead也可以暂停一下 然后在达到超时的情况下进行一些额外的错误检查。在我的情况下,我永远不应该 收到一个不完整的xml,但如果它确实发生了,这将无限制地锁定线程 没有超时:
while(!xml.atEnd()) {
QXmlStreamReader::TokenType t = xml.readNext();
if(xml.error()) {
if(xml.error() == QXmlStreamReader::PrematureEndOfDocumentError) {
cout << "reading extra data" << endl;
sock->waitForReadyRead();
xml.addData(sock->readAll());
cout << "extra data successful" << endl;
continue;
} else {
break;
}
}
...