【问题标题】:How to send a file along with its filename over QTCPSocket?如何通过 QTCPSocket 发送文件及其文件名?
【发布时间】:2012-11-27 20:23:14
【问题描述】:

是否有任何简单的方法可以将包含文件名的文件发送到服务器,以便服务器和客户端中的文件名完全相同?

这是我的代码

发件人

QString path = QApplication::applicationDirPath()+"/belajardansa.bmp";
QFile inputFile(path);
QByteArray read ;
inputFile.open(QIODevice::ReadOnly);
while(1)
{
    read.clear();
    read = inputFile.read(32768*8);
    qDebug() << "Read : " << read.size();
    if(read.size()==0)
       break;
    qDebug() << "Written : " << socket->write(read);
    socket->waitForBytesWritten();
    read.clear();
}
inputFile.close();

接收者

QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);

QByteArray read = socket->read(socket->bytesAvailable());
qDebug() << "Read : " << read.size();

QFile file(  ???); // what should I put in the bracket???
if(!(file.open(QIODevice::Append)))
{
    qDebug("File cannot be opened.");
    exit(0);
}
file.write(read);
file.close();

【问题讨论】:

    标签: qt qtcpsocket qtnetwork qtcpserver


    【解决方案1】:

    没有真正简单的方法。您必须创建自己的协议。但是,该协议通常可以是非常非常简单的协议。

    写完,简单的例子

    1. 使用QString::toUtf8() 将 QString 文件名转换为 QByteArray
    2. 将 QByteArray 的长度写入套接字为二进制 int
    3. 写入到包含文件名的 QByteArray 中的字节的套接字
    4. 将文件长度作为二进制 int 写入套接字
    5. 写入套接字文件中的字节
    6. 关闭

    阅读结束:

    1. 读取整数告诉文件名的长度
    2. 将这么多字节读取到 QByteArray
    3. 使用QString::fromUtf8()将文件名从QByteArray转换为QString
    4. 读取整数告诉数据长度
    5. 继续读取字节并写入到文件,直到获得那么多字节
    6. 关闭

    在读写时,如果要在不同的计算机之间进行通信,应该在写入前转换成网络字节序,读取后转换回主机字节序。您还可以决定定义,您使用“x86 字节排序”,任何使用不同 CPU 读取数据的人都需要转换...

    【讨论】:

    • 感谢您的回复 hyde,您的建议似乎很有用。但是作为新手,我有一个问题。如何区分传入的套接字数据,以便我可以将数据放在该协议中的正确步骤。 (正如我们所知,在 TCP 中写入的数据以某些包的形式发送。)
    • TCP/IP 是一种流协议,您可以写入和读取字节,而不是数据包。它还保证所有字节的顺序和传输。所以你可以相信你会以完全相同的顺序得到完全相同的字节(或者你会得到错误和断开连接)。这也是为什么您必须将自己的“数据包大小”写入套接字的原因,因为 TCP/IP 不会为您提供具有大小的数据包,只是字节流。
    • 还有一个澄清:您当然可以一次写入和读取多个字节的数据,这从您在写入和读取时使用的方法可以看出。只是你的写入大小丢失了,接收者不知道你是先写了 10 个字节,然后是 100 个字节,还是一次写了 110 个字节。
    【解决方案2】:
    1. 您可以创建自己的数据结构来表示文件内容及其文件名,并将其转换为 QByteArray,反之亦然。

    2. 您可以发送两个请求:第一个带有文件名,第二个带有数据。

    【讨论】:

    • 感谢您的回复汉克,您的第一个建议对我来说有点复杂,因为我是 C++ 和 Qt 的新手。你能给我一个将数据结构转换为 QByteArray 的示例代码吗?关于您的第二个建议,如何区分套接字数据,以便服务器可以识别套接字数据是否包含文件名或数据。
    猜你喜欢
    • 2018-10-23
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 2011-08-19
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多