Qt模块化笔记之network——第二个TCP程序,传输图片文件的实现(2)

本节你将了解如何传输一个文件,以图片文件示例。

在以前socket的write函数只,我们都只是写入少量的文字,大小也许还不到一K,它的写入时间极短,接收时间也极短,很少需要考虑是否保证它完整地传输到另一端。

但文件不同,文件的传输需要保证它的每一部分都传送到另一端,另一端才能将它还原。

比如我们的浏览器从网络下载文件的时候,它在下载之前就获得了需要下载的文件信息,如文件名,文件大小,进而在本地硬盘创建文件,将内容写入。从而实现下载。知道文件大小,还可以通过已接收到的字节数量,计算下载百分比。

为保证我们的文件完整地传送到另一端,我们需要让另一端先知道文件的大小等基本信息。这就需要叫做“文件头”的部分。文件头是文件的一些相关信息。

看下面发送图片的实例:

QBuffer buffer;
QByteArray dataStr;
QDataStream out( &dataStr,QIODevice::WriteOnly );
out.setVersion(QDataStream::Qt_5_2);
buffer.open(QIODevice::ReadWrite);
img.save(&buffer,"PNG");
out << qint32(buffer.size())<<QString(fileName)<< buffer.data();
Socket->write(dataStr);

img是QImage,这个类是专门用于IO的,如果直接传输QPixmap,将破坏图片内部的信息,如分辨率等,导致在另一端无法将图片还原。上面代码将图片保存到buffer中,通过dataStream将它存入QByteArray dataStr,最后用tcp socket写入dataStr。

out << qint32(buffer.size())<<QString(fileName)<< buffer.data();这一句中需要qint32等进行“修饰”,是因为,qint32代表32-bit即四个字节,表示的数字范围大小足够用了。QString也类似,不去查了,假设它2个字节。<< qint32(buffer.size())<<QString(fileName)就是传输文件头了。 buffer.data()传输数据内容。

这样,我们的数据可想像为,格式:aaaabbccccccc……。读取时,只要顺序读出来不就行了吗?

最后,图片在500K左右,我们一次性发送出去。


接收时:

connect(clientSocket,SIGNAL(readyRead()),this,SLOT(readData()));

void Client::readData()
{
QDataStream in( clientSocket );
in.setVersion(QDataStream::Qt_5_2);
if( dataSize == 0 )//dataSize是一个自己设的qint32
{
   if( clientSocket->bytesAvailable() < (sizeof(quint32)+sizeof(QString)) )
   {
        return;
   }
   in >> dataSize;//按顺序读出。先入先出顺序
   in>>fileName;//fileName是设的QString
}
if( dataSize > qint32(clientSocket->bytesAvailable()))//图片比较小,让它存在clientSocket的缓存中,直到大小满足关系,即文件内容都传输完毕后才读取出来。
{
   return;
}
QByteArray a;
in>>a;
img.loadFromData(a);//这个就是存进去的QImage了

dataSize=0;//重置为0,等待下一次传输
}



如果文件极大。比如几百M,几个G的,就不能用上述方法了。

这时,需要不断地用IO类如QFile,从源文件中read一定数量的字节,然后循环发出。接收时也要比较大小。



  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 可以使用Qt中的QTcpSocket类和QTcpServer类来实现TCP文件传输。具体步骤如下: 1. 创建一个QTcpServer对象,并在其上调用listen()方法来监听来自客户端的连接请求。 2. 当有客户端连接请求到达时,QTcpServer会触发newConnection()信号。在该信号的槽函数中,可以使用QTcpServer的nextPendingConnection()方法获取一个QTcpSocket对象来和客户端进行通信。 3. 在QTcpSocket对象上调用connectToHost()方法连接服务器端,或者使用已连接的QTcpSocket对象进行数据传输。 4. 在QTcpSocket对象上调用write()方法发送文件内容,或者在接收方使用QTcpSocket的readyRead()信号和read()方法接收文件内容。 5. 传输完成后,关闭QTcpSocket对象和QTcpServer对象。 具体实现可以参考Qt官方文档和示例程序。 ### 回答2: Qt是一个开发C++桌面应用程序的跨平台框架,它提供了丰富的类库和工具来简化程序开发。要实现TCP文件传输,可以借助Qt的网络模块。 首先,我们需要创建一个TCP服务器和一个TCP客户端。服务器端需要监听指定的端口并接受客户端连接,而客户端需要连接到服务器并发送文件数据。 在服务器端,我们可以使用QTcpSocket和QTcpServer类来创建一个TCP服务器。可以使用QTcpServer的listen方法来绑定服务器IP地址和监听的端口。一旦有客户端连接到服务器,QTcpServer会发出newConnection信号,我们可以在这个信号槽函数中处理客户端连接。 在客户端,我们同样可以使用QTcpSocket类来创建一个TCP连接。通过调用QTcpSocket的connectToHost方法,我们可以连接到服务器的IP地址和端口。一旦连接建立成功,我们可以使用QTcpSocket的write方法来发送文件数据。 为了实现文件传输,我们可以使用QFile类来打开文件并读取数据。在服务器端,可以将文件内容分割为较小的数据块,并使用QTcpSocket的write方法将这些数据块发送给客户端。在客户端,我们可以使用QTcpSocket的read方法接收服务器发送的数据块,并将其写入文件中。 在文件传输过程中,我们还可以使用QTcpSocket的readyRead和bytesWritten信号来处理读取和写入文件数据的细节,以确保数据的完整性和正确性。 通过以上步骤,我们可以使用Qt实现TCP文件传输。同时,Qt还提供了其他一些类和方法来处理网络连接的错误和异常,并提供了完善的错误处理机制来增加程序的稳定性和可靠性。 ### 回答3: 在Qt实现TCP文件传输需要使用QTcpSocket类和QFile类。首先,需要创建一个QTcpSocket的实例来处理网络连接。然后,连接到服务器并通过QTcpSocket的write方法发送文件的字节流。同时,使用QFile类来打开本地文件以便读取字节流并将其发送给服务器。 以下是一个简单的示例代码: ```cpp // 客户端: QTcpSocket socket; socket.connectToHost("服务器地址", 端口号); if (socket.waitForConnected()) { QFile file("本地文件路径"); if (file.open(QIODevice::ReadOnly)) { QByteArray data = file.readAll(); file.close(); socket.write(data); socket.waitForBytesWritten(); socket.disconnectFromHost(); } } else { // 连接失败的处理逻辑 } // 服务器: QTcpServer server; server.listen(QHostAddress::Any, 端口号); connect(&server, SIGNAL(newConnection()), this, SLOT(onNewConnection())); void YourClass::onNewConnection() { QTcpSocket *socket = server.nextPendingConnection(); connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead())); connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); } void YourClass::onReadyRead() { QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender()); QByteArray data = socket->readAll(); // 处理接收到的文件数据 } ``` 上面的代码只是实现TCP文件传输的基本框架,你还可以根据自己的需求进行相关的逻辑和错误处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值