使用QTcpSocket在两台机器之间传输文件

时间:2016-06-03 12:13:47

标签: qt sockets

我的类链接包含两台机器之间文件传输的所有功能。以下是代码及其调用顺序。

机器A发送请求以向机器B发送文件。如果B接受,则创建TCPServer:

quint16 Link::createServerToReceiveFile(QString savefile, qint64 size){

    // Initializing control variables.
    saveFile = savefile;
    numberOfBytesToReceive = size;
    bytesWritten = 0;

    // Initializing server for Download
    transferServer = new QTcpServer();
    transferServer->listen(QHostAddress::Any);
    connect(transferServer,SIGNAL(newConnection()),this,SLOT(on_transferServerHasNewConnection()));
    return transferServer->serverPort();
}

然后,机器A使用服务器端口为传输创建套接字:

void Link::createTransferSocket(quint32 ipnumber, quint16 TCPport, QString file2Transfer){
    fileToTransfer = file2Transfer;
    transferSocket = new QTcpSocket();
    transferSocket->connectToHost(QHostAddress(ipnumber),TCPport);
    connect(transferSocket,SIGNAL(connected()),this,SLOT(on_transferSocketConnected()));
    connect(transferSocket,SIGNAL(readyRead()),this,SLOT(on_readyDataFromTransfer()));
    connect(transferSocket,SIGNAL(disconnected()),this,SLOT(on_transferSocketDisconnected()));

    qWarning() << "Created transfer socket on sender";

}

这最终会将newConnection信号提供给Machine B的TCPServer:

void Link::on_transferServerHasNewConnection(){
    transferSocket = transferServer->nextPendingConnection();
    connect(transferSocket,SIGNAL(readyRead()),this,SLOT(on_readyDataFromTransfer()));    
    connect(transferSocket,SIGNAL(disconnected()),this,SLOT(on_transferSocketDisconnected()));
    qWarning() << "Created transfer socket on receiver";
    printSocketInfo();
}

在B上完成连接后,A接收连接的信号,传输可以这样开始:

void Link::on_transferSocketConnected(){

    qWarning() << "Now there is a connection so the sender is sending the info";
    printSocketInfo();

    QFileInfo info(fileToTransfer);
    if (info.size() > 0){

        qint64 bytesSent = 0;
        qint64 dataWritten;
        QFile input(fileToTransfer);
        QByteArray buffer;

        qWarning() << "Sending data for file" << fileToTransfer << "Bytes:" << info.size()  << "Status" << transferSocket->state();

        if (input.open(QIODevice::ReadOnly)){
            while (bytesSent < info.size()){

                buffer = input.read(TRANSFER_BUFFER_SIZE);

                // Adding the header to the data block
                //buffer.prepend(header.toUtf8());

                if (buffer.size() > 0){

                    dataWritten = transferSocket->write(buffer);

                    if (dataWritten != buffer.size()){
                        input.close();
                        transferError =  "There was an error transfering the file. " + transferSocket->errorString()  + " . Aborting";
                        break;
                    }
                    bytesSent = bytesSent + dataWritten;
                    //qWarning() << "The number of bytes written is" << bytesSent << "out of" << info.size();
                    qint32 update = bytesSent*100/info.size();
                    emit(updateTransferStatus(update,transferID));

                }
                else{
                    transferError =  "Error reading from file";
                    break;
                }

            }
        }
        else{
            transferError = "Could not open file " + fileToTransfer + " for reading";
        }

        // Disconnecting the socket and deleting the socket. Also making sure that no transfer is now underway.
        qWarning() << "Disconnecting after having supposedly finished. Transfer error is" << transferError << "Socket error" << transferSocket->error()
                   << "y el normal" << socket->error() << "state" << transferSocket->state();
        transferID = -1;
        transferSocket->disconnectFromHost();
        transferSocket->deleteLater();
        input.close();

    }
    else{
        transferError = "File " + fileToTransfer + " could not be found. Aborting transfer";
    }
}

每次A写入时,套接字B都应该获取readyRead()信号并将接收到的数据保存到这样的文件中:

void Link::on_readyDataFromTransfer(){

    qWarning() << "Aca toy";

    QByteArray buffer;
    QFile output(saveFile);

    if (output.open(QIODevice::Append)){
        buffer.append(socket->readAll());
        output.write(buffer);
        bytesWritten = bytesWritten + buffer.size();
    }

    output.close();

    qWarning() << "Received" << bytesWritten  << "of the file" << saveFile;

    emit(updateTransferStatus(bytesWritten*100/numberOfBytesToReceive,transferID));

    // When all the bytes were received the transfer mode is finished.
    if (bytesWritten >= numberOfBytesToReceive){
        transferID = -1;
    }

}

问题是永远不会调用最后一个函数,我也无法在套接字值(IP&#39; s和端口)中检测到任何错误,并且除了on_readyDataFromTransfer()消息之外,每个调试消息都被写入。从来没有打过这个插槽我无法弄清楚原因。此外,由于这不属于我的实际代码,我也不知道如何调试它。

有人看错了吗?

0 个答案:

没有答案