客户端向服务端发送数据
客户端
#include "server.h"
#include "ui_server.h"
#include <QtNetwork>
Server::Server(QWidget *parent) :
QDialog(parent),
ui(new Ui::Server)
{
ui->setupUi(this);
connect(&tcpServer, SIGNAL(newConnection()),
this, SLOT(acceptConnection()));
}
Server::~Server()
{
delete ui;
}
void Server::start()
{
if (!tcpServer.listen(QHostAddress::LocalHost, 6666)) {
qDebug() << tcpServer.errorString();
close();
return;
}
ui->startButton->setEnabled(false);
totalBytes = 0;
bytesReceived = 0;
fileNameSize = 0;
ui->serverStatusLabel->setText(tr("监听"));
ui->serverProgressBar->reset();
}
void Server::acceptConnection()
{
tcpServerConnection = tcpServer.nextPendingConnection();
connect(tcpServerConnection, SIGNAL(readyRead()),
this, SLOT(updateServerProgress()));
connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(displayError(QAbstractSocket::SocketError)));
ui->serverStatusLabel->setText(tr("接受连接"));
tcpServer.close();
}
void Server::updateServerProgress()
{
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_5_6);
if (bytesReceived <= sizeof(qint64)*2) {
if((tcpServerConnection->bytesAvailable() >= sizeof(qint64)*2)
&& (fileNameSize == 0)) {
in >> totalBytes >> fileNameSize;
bytesReceived += sizeof(qint64) * 2;
}
if((tcpServerConnection->bytesAvailable() >= fileNameSize)
&& (fileNameSize != 0)) {
in >> fileName;
ui->serverStatusLabel->setText(tr("接收文件 %1 …")
.arg(fileName));
bytesReceived += fileNameSize;
localFile = new QFile(fileName);
if (!localFile->open(QFile::WriteOnly)) {
qDebug() << "server: open file error!";
return;
}
} else {
return;
}
}
if (bytesReceived < totalBytes) {
bytesReceived += tcpServerConnection->bytesAvailable();
inBlock = tcpServerConnection->readAll();
localFile->write(inBlock);
inBlock.resize(0);
}
ui->serverProgressBar->setMaximum(totalBytes);
ui->serverProgressBar->setValue(bytesReceived);
if (bytesReceived == totalBytes) {
tcpServerConnection->close();
localFile->close();
ui->startButton->setEnabled(true);
ui->serverStatusLabel->setText(tr("接收文件 %1 成功!")
.arg(fileName));
}
}
void Server::displayError(QAbstractSocket::SocketError socketError)
{
qDebug() << tcpServerConnection->errorString();
tcpServerConnection->close();
ui->serverProgressBar->reset();
ui->serverStatusLabel->setText(tr("服务端就绪"));
ui->startButton->setEnabled(true);
}
void Server::on_startButton_clicked()
{
start();
}
#include "tcpclientdialog.h"
#include "ui_tcpclientdialog.h"
#include <QFileDialog>
TcpClientDialog::TcpClientDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::TcpClientDialog)
{
ui->setupUi(this);
payloadSize = 64 * 1024;
totalBytes = 0;
bytesWritten = 0;
bytesToWrite = 0;
tcpClient = new QTcpSocket(this);
connect(tcpClient, SIGNAL(connected()),
this, SLOT(startTransfer()));
connect(tcpClient, SIGNAL(bytesWritten(qint64)),
this, SLOT(updateClientProgress(qint64)));
connect(tcpClient, &QAbstractSocket::errorOccurred,
this, &TcpClientDialog::displayError);
ui->sendPushButton->setEnabled(false);
}
TcpClientDialog::~TcpClientDialog()
{
delete ui;
}
void TcpClientDialog::openFile()
{
fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty()){
ui->sendPushButton->setEnabled(true);
ui->messageLabel->setText(tr("打开文件 %1 成功!").arg(fileName));
}
}
void TcpClientDialog::send()
{
ui->sendPushButton->setEnabled(false);
bytesWritten = 0;
ui->messageLabel->setText(tr("连接中……"));
tcpClient->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt());
}
void TcpClientDialog::startTransfer()
{
localFile = new QFile(fileName);
if(!localFile->open(QFile::ReadOnly))
{
qDebug() << tr("客户端:打开文件失败!");
return;
}
totalBytes = localFile->size();
QDataStream sendOut(&outBlock, QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_5_9);
QString currentFileName = fileName.right(
fileName.size() - fileName.lastIndexOf("/") - 1);
qDebug() << "fileName" << fileName;
sendOut << qint64(0) << qint64(0) << currentFileName;
totalBytes += outBlock.size();
sendOut.device()->seek(0);
sendOut << totalBytes << qint64(outBlock.size() - sizeof(qint64)*2);
bytesToWrite = totalBytes - tcpClient->write(outBlock);
ui->messageLabel->setText(tr("已连接"));
outBlock.resize(0);
}
void TcpClientDialog::updateClientProgress(qint64 numBytes)
{
bytesWritten += (int)numBytes;
if(bytesToWrite > 0){
outBlock = localFile->read(qMin(bytesToWrite, payloadSize));
bytesToWrite -= (int)tcpClient->write(outBlock);
outBlock.resize(0);
}else{
localFile->close();
}
ui->clientProgressBar->setMaximum(totalBytes);
ui->clientProgressBar->setValue(bytesWritten);
if(bytesWritten == totalBytes){
ui->messageLabel->setText(tr("传输文件 %1 成功!").arg(fileName));
localFile->close();
tcpClient->close();
}
}
void TcpClientDialog::displayError(QAbstractSocket::SocketError socketError)
{
qDebug() << tcpClient->errorString();
tcpClient->close();
ui->clientProgressBar->reset();
ui->messageLabel->setText(tr("客户端就绪!"));
ui->sendPushButton->setEnabled(true);
}
void TcpClientDialog::on_openPushButton_clicked()
{
ui->clientProgressBar->reset();
ui->messageLabel->setText(tr("状态:等待打开文件!"));
openFile();
}
void TcpClientDialog::on_sendPushButton_clicked()
{
send();
}
服务端
#ifndef TCPSERVERDIALOG_H
#define TCPSERVERDIALOG_H
#include <QDialog>
#include <QAbstractSocket>
#include <QtNetwork>
#include <QDebug>
class QTcpSocket;
class QFile;
QT_BEGIN_NAMESPACE
namespace Ui { class TcpServerDialog; }
QT_END_NAMESPACE
class TcpServerDialog : public QDialog
{
Q_OBJECT
public:
TcpServerDialog(QWidget *parent = nullptr);
~TcpServerDialog();
private slots:
void start();
void acceptConnection();
void updateServerProgress();
void displayError(QAbstractSocket::SocketError socketError);
void on_pushButton_clicked();
private:
Ui::TcpServerDialog *ui;
QTcpServer tcpServer;
QTcpSocket *tcpServerConnection;
qint64 totalBytes;
qint64 bytesReceived;
qint64 fileNameSize;
QString fileName;
QFile *localFile;
QByteArray inBlock;
};
#endif
#include "tcpserverdialog.h"
#include "ui_tcpserverdialog.h"
TcpServerDialog::TcpServerDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::TcpServerDialog)
{
ui->setupUi(this);
connect(&tcpServer, SIGNAL(newConnection()),
this, SLOT(acceptConnection()));
}
TcpServerDialog::~TcpServerDialog()
{
delete ui;
}
void TcpServerDialog::start()
{
if(!tcpServer.listen(QHostAddress::LocalHost, 6666)){
qDebug() << tcpServer.errorString();
close();
return;
}
ui->pushButton->setEnabled(false);
totalBytes = 0;
bytesReceived = 0;
fileNameSize = 0;
ui->messageLabel->setText(tr("监听!"));
ui->progressBar->reset();
}
void TcpServerDialog::acceptConnection()
{
tcpServerConnection = tcpServer.nextPendingConnection();
connect(tcpServerConnection, &QTcpSocket::readyRead,
this, &TcpServerDialog::updateServerProgress);
connect(tcpServerConnection, &QAbstractSocket::errorOccurred,
this, &TcpServerDialog::displayError);
ui->messageLabel->setText(tr("接受连接"));
tcpServer.close();
}
void TcpServerDialog::updateServerProgress()
{
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_5_9);
if(bytesReceived <= sizeof(qint64)*2){
if((tcpServerConnection->bytesAvailable() >= sizeof(qint64)*2)
&& (fileNameSize == 0)){
in >> totalBytes >> fileNameSize;
bytesReceived += sizeof(qint64) * 2;
}
if((tcpServerConnection->bytesAvailable() >= fileNameSize)
&& (fileNameSize != 0)){
in >> fileName;
ui->messageLabel->setText(tr("接收文件 %1 ……").arg(fileName));
bytesReceived += fileNameSize;
localFile = new QFile(fileName);
if(!localFile->open(QFile::WriteOnly)){
qDebug() << "服务端:打开文件失败!";
return;
}
}else{
return;
}
}
if(bytesReceived <totalBytes){
bytesReceived += tcpServerConnection->bytesAvailable();
inBlock = tcpServerConnection->readAll();
localFile->write(inBlock);
inBlock.resize(0);
}
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(bytesReceived);
if(bytesReceived == totalBytes){
tcpServerConnection->close();
localFile->close();
ui->pushButton->setEnabled(true);
ui->messageLabel->setText(tr("接收文件 %1 成功!").arg(fileName));
}
}
void TcpServerDialog::displayError(QAbstractSocket::SocketError socketError)
{
qDebug() << tcpServerConnection->errorString();
tcpServerConnection->close();
ui->progressBar->reset();
ui->messageLabel->setText(tr("服务端就绪!"));
ui->pushButton->setEnabled(true);
}
void TcpServerDialog::on_pushButton_clicked()
{
start();
}