2012-12-10 39 views
5

是否有任何简单的方法发送文件到服务器与文件名包括在服务器和客户端的文件名是完全一样的?如何通过QTCPSocket发送文件及其文件名?

这里是我的代码

发件人

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(); 

回答

5
  1. 您可以创建自己的数据结构,将代表文件的内容和它的文件名,并将其转换到QByteArray,反之亦然。

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

+0

谢谢你的回应Hank, 你的第一个建议对我来说有点复杂因为我是C++和Qt的新手。你能给我一个示例代码来将数据结构转换为QByteArray吗? 关于您的第二个建议, 如何处理套接字数据,以便服务器可以识别套接字数据是否包含文件名或数据。 –

5

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

在使用QString::toUtf8()

  • 写入到插座的QByteArray的长度为二进制INT
  • 写入到套接字从QByteArray中包含该文件的字节

    1. 转换QString的文件名写入结束时,简单的例子来的QByteArray名称
    2. 向套接字写入文件长度为二进制int
    3. 向套接字写入文件中的字节
    4. 关闭

    在读取结束:

    1. 文件名的读取整数告诉长度
    2. 阅读很多字节从QByteArray中到QString的一个QByteArray中
    3. 转换文件名中使用QString::fromUtf8()
    4. 读取整数,告诉数据长度
    5. 保持读取字节并写入文件直到你得到了多少字节
    6. 关闭

    当写入和读出,如果你想在不同计算机之间进行沟通,你应该转换成网络字节顺序写入之前,和反读取后为主机字节顺序。你也可以决定定义,你使用“x86字节顺序”,并且任何人读取不同CPU需要的数据进行转换...

  • +0

    感谢您对hyde的回应, 您的建议似乎非常有用。但作为一个新手,我有一个问题。 如何处理传入的套接字数据,以便我可以将数据放在该协议中的正确步骤。 (正如我们所知,在某些软件包中发送的TCP写入数据。) –

    +0

    TCP/IP是一种流协议,您可以写入和读取字节,而不是数据包。它还保证所有字节的顺序和传输。所以你可以相信你会得到完全相同的顺序完全相同的字节(或者你会得到错误和断开连接)。这也是为什么你必须将自己的“数据包大小”写入套接字的原因,因为TCP/IP不会给你数据包的大小,只是字节流。 – hyde

    +0

    现在好了:) 谢谢你海德。 –