简述
TCP文件服务器的实现,可以在TCP服务器的基础上增加文件发送逻辑。参阅TCP文件服务器的实现。【https://blog.csdn.net/lusanshui/article/details/88565806 】
代码之路
直接给出完整的TCP文件服务器代码。
MyFileServer类的头文件如下:
#include <QTcpServer>
#include <QTcpSocket>
#include <QDataStream>
#include <QFile>
#include <QHostAddress>
#include <QIODevice>
#include <QThread>
class MyFileServer : public QObject
{
Q_OBJECT
public:
MyFileServer(QObject *parent = 0);
~MyFileServer();
signals:
void startSendFile(QString filename);
private slots:
void acceptFileConnection();
void updateFileProgress();
void displayError(QAbstractSocket::SocketError socketError);
void filesocketDisconnect();
void sendFile(QString filename);
private:
QString getFileFullPath(QString tmp); //获取待发送的文件路径
private:
QTcpServer *fileserver;
QTcpSocket *filesocket;
QThread *m_thread;
MyDatastream m_DATAstream;
SingleFile m_SingleFile;
}
MyFileServer类的源文件如下:
MyFileServer::MyFileServer(QObject *parent) : QObject(parent)
{
m_thread = new QThread();
filesocket = new QTcpSocket();
fileserver = new QTcpServer();
//listening
fileserver->listen(QHostAddress::Any, 6001);
connect(fileserver, SIGNAL(newConnection()), this, SLOT(acceptFileConnection()));
filesocket->moveToThread(m_thread);
fileserver->moveToThread(m_thread);
this->moveToThread(m_thread);
m_thread->start();
}
MyFileServer::~MyFileServer()
{
m_thread->quit();
m_thread->wait();
delete m_thread;
filesocket->close();
delete filesocket;
fileserver->close();
delete fileserver;
}
void MyFileServer::acceptFileConnection()
{
filesocket = fileserver->nextPendingConnection();
connect(filesocket, SIGNAL(readyRead()), this, SLOT(updateFileProgress()));
connect(filesocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(filesocket, SIGNAL(disconnected()), this, SLOT(filesocketDisconnect()));
connect(this, SIGNAL(startSendFile(QString)), this, SLOT(sendFile(QString)));
}
void MyFileServer::updateFileProgress()
{
//receive msg
if (filesocket->bytesAvailable() <= 0)
{
return;
}
QByteArray singleBuffer = filesocket->readAll();
if (singleBuffer.size() == 14 && singleBuffer[0] == 0xF7) //双方约定
{
m_SingleFile = m_DATAstream.ReadSingleFile(singleBuffer); //按约定转信息,得到文件名等信息
QString tmpFilename = m_SingleFile.fileDataInfo.strName;
QString tmpFullFilename = getFileFullPath(tmpFilename); //根据文件名得到全路径
emit startSendFile(tmpFullFilename);
}
}
void MyFileServer::displayError(QAbstractSocket::SocketError socketError)
{
qDebug() << filesocket->errorString();
filesocket->close();
}
void MyFileServer::filesocketDisconnect()
{
filesocket->deleteLater();
}
void MyFileServer::sendFile(QString filename)
{
QFile localFile(filename);
if (!localFile.open(QFile::ReadOnly))
{
qDebug() << "cannot open file which need to send!";
return;
}
QByteArray totalba = localFile.readAll();
filesocket->write(totalba);
}
QString MyFileServer::getFileFullPath(QString tmp)
{
QString fullpath;
//...
return fullpath;
}
总结
文中监听端口号6001,每收到约定好的字符串文件发送请求,解析文件名并发送文件内容。
在工程的pro文件中不要忘记把network模块加入进来。