我知道可能已经提出了一些类似的问题,但我找到的答案涵盖了非常具体的问题,我仍然没有想出来 .
在我的程序中,我正在创建一个QObject(称为QPeer),它使用QTcpSocket通过网络与另一个这样的对象进行通信 . QPeer有一个插槽,可以接受带有数据的QByteArray( sendData(QByteArray)
) . 该数组的全部内容被认为是一个'message',并将它们写入套接字 . 我想要做以下事情:每次写入消息时,我都希望接收QPeer正好发出一次信号 dataReceived(QByteArray)
,即包含整个消息的QByteArray . (注意:所有信号/插槽,包括连接QPeer及其插座的私有信号/插槽,以及 sendData(QByteArray)
等公共信号/插槽,都会在必要时使用_1525310进行序列化 . )
我使用信号 QTcpSocket::readyRead()
从套接字异步读取 . 现在我知道我不能只在sendData中调用 QTcpSocket::write()
,然后假设对于我做的每次写操作,另一端的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)然后读取该字节数;接下来用恰好那些字节发出dataReceived . 我在尝试这样做时遇到了严重的麻烦 . 例如:如果发出readyRead怎么办,我可以读取消息的 Headers ,但不是指定的字节数?或者如果仅部分收到 Headers 会怎么样?
1. How do I correctly write the header (4 byte int) to the socket?
2. How do I correctly implement the read function so that it does what I want?
欢迎任何提示 . 谢谢!
2 回答
我参与了一个符合您期望的项目,在这里看到我为我们的问题开发的解决方案,简化为更容易理解:
Edited, added support to the server deal with multiple clients.
Client.h:
Client.cpp:
Server.h:
Server.cpp:
Note: 不要使用此方法传输大文件,因为使用此方法,邮件的全部内容在发送之前都会放入内存中,这会导致内存使用率过高 . 并且因为32位有符号INT的最大值为2,147,483,647,如果输入数据的值高于字节数,则无效 . 照顾自己 .
正如您所说,您需要等待标头完全发送,然后再读取它,然后读取好的字节数并发出信号以获取数据 .
这是一个例子(未经测试):