• 13235阅读
  • 11回复

TCP文件传输 [复制链接]

上一主题 下一主题
离线heqiangpc
 
只看楼主 正序阅读 楼主  发表于: 2010-07-08
— 本帖被 XChinux 执行加亮操作(2010-10-22) —
大家好!
      我在做一个基于TCP的文件传输程序。一个Server端,一个Client端。
   Client端在连接到服务器后发送文件名。然后发送文件数据。文件名与文件数据用0x0001和0x0002分别代替,0x0003代表文件传输完成。
   传输中用的数据格式为:    
       [quint32]     [quint16]                                           [QByteArray]
        数据长度  文件名/文件数据/传输完成       文件数据
   Client端在发送完文件后发送代表文件传输完成的包。
   Server端在incomingConnection中启动一个新线程。在新线程中构建一个QTcpSocket对象。在有数据可读时对到来的数据进行处理。
   但是现在的问题是:新线程中的QTcpSocket会随机收到一个disconnected(),有时早有时晚。但是在Client端会到数据发送完成后才会
调用disconnectFromHost。调试的时候是Client端在刚刚连接上发送完文件名的那一个包后调用waitForBytesWritten(-1)时就会返回false。
错误信息是“进程计算机已经关闭连接”。

我发送端的代码是
void ntpClient::on_tcpConnected()
{
    QString filePath = ui.lineEdit_2->text();
    QString fileName = filePath;
    fileName = fileName.remove(0, fileName.lastIndexOf('/')+1);
    QFile file(filePath);
    if(!file.open(QIODevice::ReadOnly))
        throw 0;

    quint32 size;
    QByteArray outArray;
    QDataStream out(&outArray, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_3);

    out << quint16(0x0001) << fileName.toUtf8();
    size = outArray.size();
    tcpSocket->write((char*)&size, sizeof(quint32));
    tcpSocket->write(outArray.data(), size);
    if(!tcpSocket->waitForBytesWritten(-1))
    {

        messageBox(tcpSocket->errorString());
        return;
    }

    do
    {
        out.device()->seek(0);
        outArray.clear();
        out << quint16(0x0002) << file.read(0xFFF0);
        size = outArray.size();
        tcpSocket->write((char*)&size, sizeof(quint32));
        tcpSocket->write(outArray.data(), size);
        if(!tcpSocket->waitForBytesWritten(-1))
        {
            messageBox(tcpSocket->errorString());
            return;
        }
    }
    while(!file.atEnd());

    file.close();

    out.device()->seek(0);
    outArray.clear();
    out << quint16(0x0003) << tr("EOF");
    size = outArray.size();
    tcpSocket->write((char*)&size, sizeof(quint32));
    tcpSocket->write(outArray.data(), size);
    if(!tcpSocket->waitForBytesWritten(-1))
    {
        messageBox(tcpSocket->errorString());
        return;
    }
    tcpSocket->waitForDisconnected(-1);
}

接收端的代码是:
void clientThread::readData()
{
    if(blockSize == 0)
    {
        if(tcpSocket->bytesAvailable() < sizeof(quint32))
            return;
        tcpSocket->read((char*)&blockSize, quint64(sizeof(quint32)));
        //qDebug() << "Recved block size " << blockSize << ".";
        //qDebug() << "\tFrom: " << tcpSocket->peerAddress().toString() << ", port: " << tcpSocket->peerPort() << ".";
    }

    if(tcpSocket->bytesAvailable() < quint64(blockSize))
        return;
    QByteArray bufArray;
    bufArray = tcpSocket->read(blockSize);
    proccessData(bufArray);
    blockSize = 0;
}

void clientThread::proccessData(QByteArray &array)
{
    QDataStream in(&array, QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_4_3);

    quint16 key;
    QByteArray data;
    in >> key >> data;
    qDebug() << "\tKey: " << key << "\tDataSize: " << data.size();
    if(key == 0x0001)
    {
        fileName = fileName.fromUtf8(data.data());
        file.setFileName(fileName);
        if(file.exists(fileName))
        {
            qDebug() << "File was exists. i will remove it.";
            //tcpSocket->disconnectFromHost();
            //tcpSocket->waitForDisconnected();
            file.remove(fileName);
            //emit finished();
        }
        if(!file.open(QIODevice::WriteOnly))
        {
            qDebug() << "File can not be opend.";
            throw 2;
        }
        qDebug() << "Store file " << file.fileName();
    }
    if(key == 0x0002)
    {
        qDebug() << "Wite data to file";
        file.write(data);
        file.flush();
    }
    if(key == 0x0003)
    {
        qDebug() << "Finished.";
        file.close();
        tcpSocket->disconnectFromHost();
        emit finished();
    }
}


大家帮我看看是什么问题啊。
描述:服务端代码
附件: ntpserver.cpp (1 K) 下载次数:50
附件: ntpserver.h (1 K) 下载次数:39
附件: clientthread.h (1 K) 下载次数:39
描述:接收线程代码
附件: clientthread.cpp (3 K) 下载次数:44
描述:发送端代码
附件: ntpclient.cpp (3 K) 下载次数:47
离线devplus
只看该作者 11楼 发表于: 2012-06-10
离线jetcai1900
只看该作者 10楼 发表于: 2011-03-21
大家很关心的呀,请解答,谢谢
离线liang6
只看该作者 9楼 发表于: 2011-02-18
传个完整的呀
离线liang6
只看该作者 8楼 发表于: 2011-02-18
文件损坏
离线spy0578
只看该作者 7楼 发表于: 2010-12-27
引用第2楼heqiangpc于2010-07-12 08:47发表的  :
问题已经解决了,原来QTcpSocket在readReady这个信号上只是在数据到来的时候才会触发。数据如果还没有处理完,他就不会再发送这个信号了。只要在接收端检查并处理完数据就可以了。
这个论坛的人怎么都不回答我的问题,是太简单了吗??


请详细说一下如何解决啊
离线spy0578
只看该作者 6楼 发表于: 2010-12-27
只要在接收端检查并处理完数据就可以了。

LZ这句话如何理解
?????
离线tangji612

只看该作者 5楼 发表于: 2010-10-06
请问兄弟是如何解决问题的,本人也碰到了同样的问题,搞了半天但还是解决不了,
请指教一下,谢谢啦!
离线tangji612

只看该作者 4楼 发表于: 2010-09-29
楼上能否麻烦发一份修改过完整代码给小弟
本人正在研究相关方面的课程设计,特向楼主请教!
谢谢!十分感谢!
邮箱:tangji612@163.com
谢谢啦!!
离线lexdene
只看该作者 3楼 发表于: 2010-07-21
太长了……懒……
离线heqiangpc
只看该作者 2楼 发表于: 2010-07-12
问题已经解决了,原来QTcpSocket在readReady这个信号上只是在数据到来的时候才会触发。数据如果还没有处理完,他就不会再发送这个信号了。只要在接收端检查并处理完数据就可以了。
这个论坛的人怎么都不回答我的问题,是太简单了吗??
离线heqiangpc
只看该作者 1楼 发表于: 2010-07-09
没有人回答啊。。。。。。。
快速回复
限100 字节
 
上一个 下一个