一、客户端
这次我们先讲解客户端,在客户端里我们与服务器进行连接,一旦连接成功,就会发出connected()信号,这时我们就进行文件的发送。
发送数据时我们要先发送文件的总大小,然后文件名长度,然后是文件名,这三部分我们合称为文件头结构,最后再发送文件数据。所以在发送函数里我们就要进行相应的处理,当然,在服务器的接收函数里我们也要进行相应的处理。对于文件大小,这次我们使用了qint64,它是64位的,可以表示一个很大的文件了。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
槽函数实现:
①实现打开文件函数
void Widget::openFile() //打开文件
{
fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty())
{
ui->sendButton->setEnabled(true);
ui->clientStatusLabel->setText(tr(“打开文件%1 成功!”)
.arg(fileName));
}
}
该函数将在下面的“打开”按钮单击事件槽函数中调用。
②实现连接函数。
void Widget::send() //连接到服务器,执行发送
{
ui->sendButton->setEnabled(false);
bytesWritten = 0;
//初始化已发送字节为0
ui->clientStatusLabel->setText(tr(“连接中…”));
tcpClient->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt());//连接
}
该函数将在“发送”按钮的单击事件槽函数中调用。
③实现文件头结构的发送
void Widget::startTransfer() //实现文件大小等信息的发送
{
localFile = new QFile(fileName);
if(!localFile->open(QFile::ReadOnly))
{
qDebug() << "open file error!";
return;
}
totalBytes = localFile->size();
//文件总大小
QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_4_6);
QString currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1);
sendOut << qint64(0) << qint64(0) << currentFileName;
//依次写入总大小信息空间,文件名大小信息空间,文件名
totalBytes += outBlock.size();
//这里的总大小是文件名大小等信息和实际文件大小的总和
sendOut.device()->seek(0);
sendOut<<totalBytes<<qint64((outBlock.size() - sizeof(qint64)*2));
//返回outBolock的开始,用实际的大小信息代替两个qint64(0)空间
bytesToWrite = totalBytes - tcpClient->write(outBlock);
//发送完头数据后剩余数据的大小
ui->clientStatusLabel->setText(tr("已连接"));
outBlock.resize(0);
}
④实现错误处理函数。
void Widget::displayError(QAbstractSocket::SocketError) //显示错误
{
qDebug() << tcpClient->errorString();
tcpClient->close();
ui->clientProgressBar->reset();
ui->clientStatusLabel->setText(tr(“客户端就绪”));
ui->sendButton->setEnabled(true);
}