当前位置: 代码迷 >> QT开发 >> tcp传输中诡异的有关问题(下一贴不知道为什么变成404了)
  详细解决方案

tcp传输中诡异的有关问题(下一贴不知道为什么变成404了)

热度:80   发布时间:2016-04-25 04:33:00.0
tcp传输中诡异的问题(上一贴不知道为什么变成404了)
使用Qt的qtcpsocket和qtcpserver类构建一个文件传输的服务端和客户端,客户端请求一个文件,服务器想客户端发送文件,可是客户端总是无法接收全部的包,比如把一个文件切分成1500个包,客户端每次只能接收1300个左右。
  直接使用原始的socket编写的话,是没有任何问题,大文件传输也正常
  但是Qt就不行,我做过测试,如果每次发送后,客户端回应服务器的话,就没有问题,可以接收全部。没有回应,一直接收的话,就会造成最后的一部分包无法不能接收,不知道是什么原因,可能是因为服务器没有发出。
  测试如下,真不知道错在哪里
C/C++ code
客户端:// main.cpp#include <QtCore/QCoreApplication>#include "transfer_clt.h"int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);        transfer_clt clt;    return a.exec();}// transfer_clt.h#ifndef TRANSFER_CLT_H#define TRANSFER_CLT_H#include <QObject>#include <QtCore>#include <QtNetwork>#include <QFile>#define DOWN_GET_FILE   10#define DOWN_TRANSFER   11#define DOWN_OVER       12class transfer_clt : public QObject{    Q_OBJECTpublic:    explicit transfer_clt(QObject *parent = 0);    signals:    public slots:    void on_connected();    void on_readyRead();    void on_error(QAbstractSocket::SocketError socketError);private:    QTcpSocket *tcpSocket;    int count;    QFile *file;};#endif // TRANSFER_CLT_H// transfer_clt.cpp#include "transfer_clt.h"transfer_clt::transfer_clt(QObject *parent) :    QObject(parent){    tcpSocket = new QTcpSocket;    count = 0;    connect(tcpSocket, SIGNAL(connected()), this, SLOT(on_connected()));    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_readyRead()));    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),            this, SLOT(on_error(QAbstractSocket::SocketError)));    tcpSocket->connectToHost("127.0.0.1", 9100);}void transfer_clt::on_connected (){    qDebug () << "require file";    QString fileName = "Sweety.txt";    // 请求的文件    file = new QFile(fileName);    if (!file->open(QFile::WriteOnly )) {        qDebug () << tr("cannot open file");        return;    }    QByteArray outBlock;    QDataStream out(&outBlock, QIODevice::WriteOnly);    out << DOWN_GET_FILE << fileName;    tcpSocket->write(outBlock);}void transfer_clt::on_error (QAbstractSocket::SocketError){    qDebug() << "on_error() : " << tcpSocket->errorString();    tcpSocket->close ();}void transfer_clt::on_readyRead(){    int type;    QDataStream in (tcpSocket);    QByteArray inBlock;    tcpSocket->bytesAvailable();    in >> type;    if(type == DOWN_TRANSFER) {        in >> inBlock;                    file->write(inBlock);          qDebug() << "count = " << count++ << " size: " << inBlock.size();    } else if (type == DOWN_OVER) {        qDebug() << "end" ;        file->close ();        tcpSocket->close ();    }}// 服务端://main.cpp#include <QtCore/QCoreApplication>#include "transfer_srv.h"int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);        transfer_srv srv;    return a.exec();}// transfer_srv.h#ifndef TRANSFER_SRV_H#define TRANSFER_SRV_H#include <QObject>#include <QtCore>#include <QtNetwork>#include <QFile>#define DOWN_GET_FILE   10#define DOWN_TRANSFER   11#define DOWN_OVER       12class transfer_srv : public QObject{    Q_OBJECTpublic:    explicit transfer_srv(QObject *parent = 0);    signals:    public slots:    void on_newConnection();    void on_readyRead();    void on_bytesWritten(qint64 numBytes);    void on_error(QAbstractSocket::SocketError socketError);private:    QTcpSocket *tcpSocket;    QTcpServer tcpServer;    int count;    QFile *file;    qint64 byteToWrite;   };#endif // TRANSFER_SRV_H// transfer_srv.cpp#include "transfer_srv.h"qint64 blockSize = 4*1024;transfer_srv::transfer_srv(QObject *parent) :    QObject(parent){    count = 0;          while (!tcpServer.isListening()           && !tcpServer.listen(QHostAddress::LocalHost, 9100))    {        qDebug() << "Server cannot listen on port " << 9100;        return;    }    connect(&tcpServer, SIGNAL(newConnection()),            this, SLOT(on_newConnection()));    qDebug() << "start service...";}void transfer_srv::on_newConnection (){    tcpSocket = tcpServer.nextPendingConnection();    qDebug() << "connection to : " << tcpSocket;    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(on_readyRead()));    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),            this, SLOT(on_error(QAbstractSocket::SocketError)));    connect(tcpSocket, SIGNAL(bytesWritten(qint64)),            this, SLOT(on_bytesWritten(qint64))); }void transfer_srv::on_error (QAbstractSocket::SocketError){    qDebug() << "on_error() : " << tcpSocket->errorString();    tcpSocket->close ();    count = 0;}void transfer_srv::on_readyRead(){    int type;    QDataStream in (tcpSocket);    in >> type;    if(type == DOWN_GET_FILE) {        QString fileName;         in >> fileName;        qDebug () << "require file : " << fileName;        file = new QFile(fileName);        if (!file->open(QFile::ReadOnly )) {            qDebug () << tr("cannot open file");            return;        }        byteToWrite = file->size();        QByteArray tmp;        tmp = file->read(qMin(blockSize, byteToWrite));        byteToWrite -= qMin(blockSize, byteToWrite);        QByteArray outBlock;        QDataStream out(&outBlock, QIODevice::WriteOnly);        out << DOWN_TRANSFER << tmp;        int num = tcpSocket->write (outBlock);        qDebug () << "count = " << count ++ << "size: " << num ;    }}void transfer_srv::on_bytesWritten(qint64 numBytes){    static bool status = true;    if(status == false)        return;    QByteArray outBlock;    QDataStream out(&outBlock, QIODevice::WriteOnly);    if(byteToWrite > 0) {        QByteArray tmp;        tmp = file->read(qMin(blockSize, byteToWrite));        byteToWrite -= qMin(blockSize, byteToWrite);        out << DOWN_TRANSFER << tmp;        tcpSocket->write (outBlock);        qDebug () << "count = " << count ++ << "size: " << outBlock.size();    } else {        tcpSocket->flush();        qDebug() << "end" ;        out << DOWN_OVER ;        file->close ();        tcpSocket->write (outBlock);           tcpSocket->flush();        status = false;    }}
  相关解决方案