Qt---多线程应用的例子

来源:互联网 发布:java获取文件修改时间 编辑:程序博客网 时间:2024/04/20 19:05

这里写图片描述

服务器端

这里写图片描述

TimeThread创建TcpSocket,负责实现Run()函数,发送服务器端信息,然后断开连接。
TimeSever中创建TimeThread,实incomingConnection(int socketDescriptor)函数每当有新的客户端连接时,创建新的线程,将线程结束函数与对话框中的退出按钮绑定,然后启动线程
Dialog中创建TimeSever,对客户端监听

.pro中添加:

QT       += network

timethread.h

#ifndef TIMETHREAD_H#define TIMETHREAD_H#include <QThread>#include <QtNetwork>#include <QTcpSocket>class TimeThread : public QThread{    Q_OBJECTpublic:    TimeThread(int socketDescriptor,QObject *parent=0);    void run();signals:    void error(QTcpSocket::SocketError socketError);private:    int socketDescriptor;};#endif // TIMETHREAD_H

timethread.cpp

#include "timethread.h"#include <QDateTime>#include <QByteArray>#include <QDataStream>TimeThread::TimeThread(int socketDescriptor, QObject *parent)    :QThread(parent), socketDescriptor(socketDescriptor){}void TimeThread::run(){    QTcpSocket tcpSocket;    if(!tcpSocket.setSocketDescriptor(socketDescriptor))    {        emit error(tcpSocket.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();}

timeserver.h

#ifndef TIMESERVER_H#define TIMESERVER_H#include <QTcpServer>class Dialog;  //服务器端的声明class TimeServer:public QTcpServer{    Q_OBJECTpublic:    TimeServer(QObject *parent = 0);protected:    void incomingConnection(int socketDescriptor);private:    Dialog *dlg;};#endif // TIMESERVER_H

timeserver.cpp

#include "timeserver.h"#include "timethread.h"#include "dialog.h"TimeServer::TimeServer(QObject *parent): QTcpServer(parent){    dlg = (Dialog *)parent;}void TimeServer::incomingConnection(int socketDescriptor){    TimeThread *thread = new TimeThread(socketDescriptor, 0);    connect(thread, SIGNAL(finished()), dlg, SLOT(slotShow()));    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()), Qt::DirectConnection);    thread->start();}

dialog.h

#ifndef DIALOG_H#define DIALOG_H#include <QDialog>#include <QLabel>#include <QPushButton>class TimeServer;class Dialog:public QDialog{    Q_OBJECTpublic:    Dialog(QWidget *parent = 0);    ~Dialog();public slots:    void slotShow();private:    QLabel *Label1;    QLabel *Label2;    QPushButton *quitBtn;    TimeServer *timeServer;    int count;};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"#include <QHBoxLayout>#include <QVBoxLayout>#include <QMessageBox>#include "timeserver.h"Dialog::Dialog(QWidget *parent): QDialog(parent){    setWindowTitle(tr("多线程时间服务器"));    Label1 =new QLabel(tr("服务器端口:"));    Label2 = new QLabel;    quitBtn = new QPushButton(tr("退出"));    QHBoxLayout *BtnLayout = new QHBoxLayout;    BtnLayout->addStretch(1);    BtnLayout->addWidget(quitBtn);    BtnLayout->addStretch(1);    QVBoxLayout *mainLayout = new QVBoxLayout(this);    mainLayout->addWidget(Label1);    mainLayout->addWidget(Label2);    mainLayout->addLayout(BtnLayout);    connect(quitBtn, SIGNAL(clicked()), this, SLOT(close()));    count=0;    timeServer = new TimeServer(this);    if(!timeServer->listen())    {        QMessageBox::critical(this,tr("多线程时间服务器"),        tr("无法启动服务器:%1.").arg(timeServer->errorString()));        close();        return;    }    Label1->setText(tr("服务器端口:%1.").arg(timeServer->serverPort()));}Dialog::~Dialog(){}void Dialog::slotShow(){    Label2->setText(tr("第%1次请求完毕。").arg(++count));}

main.cpp

#include "dialog.h"#include <QApplication>/* *TimeThread创建TcpSocket,负责实现Run()函数,发送服务器端信息,然后断开连接 *TimeSever中创建TimeThread,实现incomingConnection(int socketDescriptor)函数 *每当有新的客户端连接时,创建新的线程,将线程结束函数与对话框中的退出按钮绑定,然后启动线程 *Dialog中创建TimeSever,对客户端监听 */int main(int argc, char *argv[]){    QApplication a(argc, argv);    Dialog w;    w.show();    return a.exec();}

客户端

这里写图片描述

初始化中建立socket,点击“获取时间”按钮后,socket连接服务器,
当服务器发送来数据时,信号函数readyRead()执行,触readTime()函数获取服务器端时间。
在读取数据时,采用QDataStream

.pro

QT       += network

timeclient.h

#ifndef TIMECLIENT_H#define TIMECLIENT_H#include <QDialog>#include <QLabel>#include <QLineEdit>#include <QPushButton>#include <QDateTimeEdit>#include <QTcpSocket>#include <QAbstractSocket>class TimeClient : public QDialog{    Q_OBJECTpublic:    TimeClient(QWidget *parent = 0);    ~TimeClient();public slots:    void enableGetBtn();    void getTime();    void readTime();    void showError(QAbstractSocket::SocketError socketError);private:    QLabel *serverNameLabel;    QLineEdit *serverNameLineEdit;    QLabel *portLabel;    QLineEdit *portLineEdit;    QDateTimeEdit *dateTimeEdit;    QLabel *stateLabel;    QPushButton *getBtn;    QPushButton *quitBtn;    uint time2u;    QTcpSocket *tcpSocket;};#endif // TIMECLIENT_H

timeclient.cpp

#include "timeclient.h"#include <QHBoxLayout>#include <QVBoxLayout>#include <QGridLayout>#include <QDataStream>#include <QMessageBox>TimeClient::TimeClient(QWidget *parent): QDialog(parent){    setWindowTitle(tr("多线程时间服务客户端"));    serverNameLabel =new QLabel(tr("服务器名:"));    serverNameLineEdit = new QLineEdit("Localhost");    portLabel =new QLabel(tr("端口:"));    portLineEdit = new QLineEdit;    QGridLayout *layout = new QGridLayout;    layout->addWidget(serverNameLabel, 0, 0);    layout->addWidget(serverNameLineEdit, 0, 1);    layout->addWidget(portLabel, 1, 0);    layout->addWidget(portLineEdit, 1, 1);    dateTimeEdit = new QDateTimeEdit(this);    QHBoxLayout *layout1 = new QHBoxLayout;    layout1->addWidget(dateTimeEdit);    stateLabel =new QLabel(tr("请首先运行时间服务器!"));    QHBoxLayout *layout2 = new QHBoxLayout;    layout2->addWidget(stateLabel);    getBtn = new QPushButton(tr("获取时间"));    getBtn->setDefault(true);    getBtn->setEnabled(false);    quitBtn = new QPushButton(tr("退出"));    QHBoxLayout *layout3 = new QHBoxLayout;    layout3->addStretch();    layout3->addWidget(getBtn);    layout3->addWidget(quitBtn);    QVBoxLayout *mainLayout = new QVBoxLayout(this);    mainLayout->addLayout(layout);    mainLayout->addLayout(layout1);    mainLayout->addLayout(layout2);    mainLayout->addLayout(layout3);    connect(serverNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableGetBtn()));    connect(portLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableGetBtn()));    connect(getBtn, SIGNAL(clicked()), this, SLOT(getTime()));    connect(quitBtn, SIGNAL(clicked()), this, SLOT(close()));    tcpSocket = new QTcpSocket(this);    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readTime()));    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(showError(QAbstractSocket::SocketError)));    portLineEdit->setFocus();}TimeClient::~TimeClient(){}void TimeClient::enableGetBtn(){    getBtn->setEnabled(!serverNameLineEdit->text().isEmpty() && !portLineEdit->text().isEmpty());}void TimeClient::getTime(){    getBtn->setEnabled(false);    time2u =0;    tcpSocket->abort();  //取消已有连接    tcpSocket->connectToHost(serverNameLineEdit->text(), portLineEdit->text().toInt());}void TimeClient::readTime(){    QDataStream in(tcpSocket);    in.setVersion(QDataStream::Qt_4_3);    if(time2u==0)    {        if(tcpSocket->bytesAvailable()<(int)sizeof(uint))            return;        in >> time2u;    }    dateTimeEdit->setDateTime(QDateTime::fromTime_t(time2u));    getBtn->setEnabled(true);}void TimeClient::showError(QAbstractSocket::SocketError socketError){    switch (socketError)    {    case QAbstractSocket::RemoteHostClosedError:        break;    case QAbstractSocket::HostNotFoundError:         QMessageBox::information(this, tr("时间服务客户端"), tr("主机不可达!"));         break;    case QAbstractSocket::ConnectionRefusedError:         QMessageBox::information(this, tr("时间服务客户端"), tr("连接被拒绝!"));         break;    default:        QMessageBox::information(this, tr("时间服务客户端"),tr("产生如下错误: %1.").arg(tcpSocket->errorString()));    }    getBtn->setEnabled(true);}

main.cpp

#include "timeclient.h"#include <QApplication>/* * 初始化中建立socket,点击“获取时间”按钮后,socket连接服务器, * 当服务器发送来数据时,信号函数readyRead()执行,触发readTime()函数获取服务器端时间 * 在读取数据时,采用QDataStream */int main(int argc, char *argv[]){    QApplication a(argc, argv);    TimeClient w;    w.show();    return a.exec();}
0 0
原创粉丝点击