1,多线程应用实例服务器
2,源码:
#ifndef TIMESERVER_H
#define TIMESERVER_H
#include <QObject>
#include <QTcpServer>
#include "timethread.h"
#include "mainwindow.h"
class MainWindow;
class TimeServer : public QTcpServer
{
Q_OBJECT
public:
TimeServer(QObject *parent);
MainWindow *mainWindow;
protected:
void incomingConnection(int socketDescriptor); //重写此虚函数,这个函数在TCP服务端有新的连接是被调用
};
#endif // TIMESERVER_H
#include "timeserver.h"
TimeServer::TimeServer(QObject *parent): QTcpServer(parent)
{
mainWindow = (MainWindow *)parent;
}
void TimeServer::incomingConnection(int socketDescriptor)
{
TimeThread *thread = new TimeThread(socketDescriptor, 0);
connect(thread, SIGNAL(finished()), mainWindow, SLOT(slotShow()));
//将上述创建的线程结束消息函数finished()关联到线程自身的槽函数deleteLater()用于结束线程,此操作中,因为信号是在同一个线程中的,
//所以使用了直接连接方式,故最后一个参数可以省略而使用Qt的自动连接选择方式
//由于工作线程中存在网络上网络时间,所以不能被外界线程销毁,这里使用了延迟销毁韩式deleteLater()保证由工作线程自身销毁
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()), Qt::DirectConnection);
//启动上述创建的线程
thread->start();
}
#ifndef TIMETHREAD_H
#define TIMETHREAD_H
#include <QObject>
#include <QThread>
#include <QtNetwork>
#include <QTcpSocket>
#include <QDateTime>
#include <QByteArray>
#include <QDataStream>
class TimeThread : public QThread
{
Q_OBJECT
public:
TimeThread(int socketDescriptor, QObject *parent = 0);
void run(); //重写此虚函数
signals:
void error(QTcpSocket::SocketError socketError); //出错信号
private:
int socketDescriptor; //套接字描述符
};
#endif // TIMETHREAD_H
#include "timethread.h"
TimeThread::TimeThread(int socketDescriptor, QObject *parent) : QThread(parent), socketDescriptor(socketDescriptor)
{
}
void TimeThread::run()
{
QTcpSocket tcpSocket; //创建一个QTcpSocket类
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) //将以上创建的QTcpSocket类置以从构造函数中传入的套接字描述符
{ //用于向客户端传回服务器端的当前时间
emit error(tcpSocket.error()); //如果出错,则发送error()信号报告错误
return;
}
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_3);
uint time2u = QDateTime::currentDateTime().toTime_t(); //获取当前时间
out << time2u;
tcpSocket.write(block); //将获得的当前时间传回客户端
tcpSocket.disconnectFromHost(); //断开连接
tcpSocket.waitForDisconnected(); //等待返回
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
#include "timeserver.h"
namespace Ui {
class MainWindow;
}
class TimeServer;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void slotShow();
private:
Ui::MainWindow *ui;
TimeServer *timeServer;
int count;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
count = 0;
timeServer = new TimeServer(this);
if (!timeServer->listen())
{
QMessageBox::critical(this, tr("多线程时间服务器"),tr("无法启动服务器: %1.").arg(timeServer->errorString()));
close();
return;
}
ui->port->setText(QString::number(timeServer->serverPort()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slotShow()
{
ui->nums->setText(QString::number(++count));
}
3,效果: