我在单个应用程序中执行 TCP 文件客户端 - 服务器。
首先,我每 50000 字节发送文件名和文件的和平。
客户:
void client::sendFile(QString path)
{
QDataStream out(cl);
QFile toSend(path);
if (toSend.open(QIODevice::ReadOnly))
{
int s = 0;
QFileInfo fileInfo(toSend.fileName());
QString fileName(fileInfo.fileName());
out << fileName;
while (!toSend.atEnd())
{
QByteArray rawFile;
rawFile = toSend.read(50000);
out << rawFile;
qDebug() << "ToSend"<<rawFile.size();
s+=rawFile.size();
}
qDebug() << "Total:" << s;
}
}
Run Code Online (Sandbox Code Playgroud)
......我猜这是正确的
服务器(ReadyRead 插槽):
void server::receive()
{
QTcpSocket *sender = (QTcpSocket*) this->sender();
QDataStream in(sender);
QString fName;
in >> fName;
QFile newFile("D:\\"+fName);
if (newFile.open(QIODevice::WriteOnly))
{
while(sender->bytesAvailable())
{
QByteArray z;
in >> z;
newFile.write(z);
qDebug () << "Received " << z.size();
}
newFile.close();
}
}
Run Code Online (Sandbox Code Playgroud)
......这是问题:while第一次迭代后坏了。
看:
ToSend 50000
ToSend 50000
ToSend 50000
ToSend 31135
Total: 181135
Received 50000
Run Code Online (Sandbox Code Playgroud)
如您所见,只收到了 1 个区块而不是 4 个。
如何解决这个问题?为什么bytesAvailable不应该返回 0?知道这种通过 tcp 接收文件的好方法是否也很好:)
可能是因为只有这一包可用。在发送数据之前,您需要就文件大小进行协商。然后等待所有数据传输完毕。处理完前 50k 数据后,BytesAvailable() 将返回 false。如果您再次调用 bytesAvailable() 等待 1 秒,您可能会得到另一个数据包。
在发送数据之前实现一个 4 字节的“大小数据包”并检查正在接收的那些字节。
所以你的协议将是:
另一种选择是使用预定义的结束数据包,但如果您的文件可以在原始数据中包含此数据包,则这可能很危险。如果您可以确保您的数据不包含您的最终数据包,您最终将实现该协议:
| 归档时间: |
|
| 查看次数: |
4906 次 |
| 最近记录: |