文章目录
- 服务器
- 客户端
思路
刚开始学是把tcp放到主线程的.
现在多线程就是把tcp放到新开辟的线程即可,和放在主线程的操作一样
服务器
- 重写
void QTcpServer :: incomingConnection(qintptr socketDescriptor)
函数
有新连接的时候QTcpServer先调用此虚函数,参数socketDescriptor
是原始的套接字.获得原始套接字之后我们便可以进行处理
myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
class MyThread;
class MyServer : public QTcpServer
{
Q_OBJECT
public:
MyServer(QWidget *parent = 0);
virtual void incomingConnection(qintptr socketDescriptor);
signals:
void sendReceivedFilename(const QString &fileName);
};
#endif // MYSERVER_H
myserver.cpp
#include "myserver.h"
#include "mythread.h"
#include <QDebug>
MyServer::MyServer(QWidget *parent)
{
}
void MyServer::incomingConnection(qintptr socketDescriptor)
{
static int i = 0;
MyThread *thread = new MyThread(0, socketDescriptor);
thread->start();
connect(thread, &MyThread::finished, [&]{
qDebug() << "thread is over";
});
connect(thread, &MyThread::finished, &MyThread::deleteLater);
connect(thread, &MyThread::sendReceivedFileName, this, &MyServer::sendReceivedFilename);
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QWidget>
class MyTcpSocket;
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread(QWidget *parent, qintptr socket);
private:
qintptr p;
MyTcpSocket *socket;
virtual void run();
signals:
void sendReceivedFileName(const QString &fileName);
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include "mysocket.h"
#include <QDebug>
MyThread::MyThread(QWidget *parent, qintptr socket) : QThread(parent)
{
this->p = socket;
connect(this, SIGNAL(finished()), SLOT(deletLater()));
}
void MyThread::run()
{
MySocket *socket = new MySocket(0, this->p);
connect(socket, &MySocket::disconnected, this, &MyThread::quit, Qt::DirectConnection);
connect(socket, &MySocket::sendReceivedFileName, this, &MyThread::sendReceivedFileName);
this->exec();
}
mysocket.h
#ifndef MYSOCKET_H
#define MYSOCKET_H
#include <QTcpSocket>
#include <QFile>
class MySocket : public QTcpSocket
{
Q_OBJECT
public:
MySocket(QWidget *parent, qintptr socket);
//处理新来的链接
public slots:
void on_connected();
public:
QFile *file;
QByteArray inBlock, outBlcok;
int photoCount = 0;
qint64 gotBytes = 0, fileBytes, fileNameSize, bytesReceived;
qint64 fileSize, sendTotalBytes, bytesToWrite, bytesWritten;
QString fileName;
QString receivedMd5;
int socketFlag;
int photoN;
int currentLocation;
QStringList fileNameList;
bool updateVersion;
QString Tips;
bool firstConnection = false;
void replyMd5(bool boole = true);
void sendFile(bool boole = true);
signals:
void sendReceivedFileName(const QString &fileName);
};
#endif // MYSOCKET_H
mysocket.cpp
#include "mysocket.h"
#include <QDataStream>
#include <QCryptographicHash>
#include <QSettings>
#include <QMessageBox>
#include <QDebug>
enum socketFlag{
md5 = 1,
versionFlag
};
MySocket::MySocket(QWidget *parent, qintptr socket) : QTcpSocket(0)
{
this->setSocketDescriptor(socket);
connect(this, SIGNAL(readyRead()), this, SLOT(on_connected()));
bytesReceived = 0;
gotBytes = 0;
fileBytes = 0;
fileNameSize = 0;
connect(this, &MySocket::disconnected, []{
qDebug() << "disconnected";
});
}
void MySocket::on_connected()
{
//读到数据的操作
qDebug() << "conn";
}
客户端
h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "mytcpsockets.h"
#include <QTimer>
class QTcpSocket;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
signals:
void con(const QString &ip, int port);
void discon();
private:
Ui::MainWindow *ui;
QTcpSocket *socket;
QHash<int, QTcpSocket *> m_hash;
MyTcpSockets *m_socket = nullptr;
QTimer tm;
};
#endif // MAINWINDOW_H
cpp文件
void MainWindow::on_pushButton_4_clicked()
{
//线程发送
int b = ui->listWidget->count();
QThread *th = new QThread;
th->start();
for (int i = 0; i < b; i++)
{
QString fileName = ui->listWidget->item(i)->text();
MySocketTwo *two = new MySocketTwo(fileName, i);
connect(this, &MainWindow::con, two, &MySocketTwo::cnt, Qt::QueuedConnection);
two->moveToThread(th);
}
emit this->con(ui->lineEdit->text(), 6666);
return ;
}
mysockettwo.h
#ifndef MYSOCKETTWO_H
#define MYSOCKETTWO_H
#include <QTcpSocket>
#include <QIODevice>
#include <QHostAddress>
class QFile;
class MySocketTwo : public QTcpSocket
{
Q_OBJECT
public:
MySocketTwo(QString &fileName, int n, QObject *parent = 0);
qint64 totalBytes, receivedBytes, sendBytes;
QByteArray byteArray;
int number = 0;
QFile *file;
QString fileName;
public slots:
void cnt(const QString &ip, const int &port);
signals:
void sendProgress(const int &i, const int &n);
void sendData(const int &i, const QString &str);
};
#endif // MYSOCKETTWO_H
mysockettwo.cpp
#include "mysockettwo.h"
#include <QFile>
#include <QDataStream>
#include <QTcpSocket>
#include <QFileInfo>
#include <QCryptographicHash>
MySocketTwo::MySocketTwo(QString &fileName, int n, QObject *parent) : QTcpSocket(parent),
totalBytes(0), receivedBytes(0), sendBytes(0)
{
//初始化信号
connect(this, &MySocketTwo::connected, this, &MySocketTwo::newFile);
this->number = n;//分配序号
this->fileName = fileName;
}
void MySocketTwo::cnt(const QString &ip, const int &port)
{
this->connectToHost(ip, port);
qDebug() << this->waitForConnected(5000);
qDebug() << "connect";
}
void MySocketTwo::newFile()
{
//连接上服务器之后的操作
}