当有客户请求到达时,服务器将启动一个新的进程为它返回当前时间,服务完毕后这个线程将自动退出。

运行截图如下:

服务端:

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

timeserver.h

#ifndef TIMESERVER_H
#define TIMESERVER_H#include <QObject>
#include <QTcpServer>class Dialog;class TimeServer : public QTcpServer
{Q_OBJECT
public:TimeServer(QObject *parent=0);
protected:void incomingConnection(int socketDescriptor);
private:Dialog *dlg;
};#endif // TIMESERVER_H

timethread.h

#ifndef TIMETHREAD_H
#define TIMETHREAD_H
#include <QObject>
#include <QThread>
#include <QTcpSocket>
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

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>int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}

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();
}

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();
}

客户端:

timeclient.h

#ifndef TIMECLIENT_H
#define TIMECLIENT_H#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QDateTimeEdit>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QTimerEvent>class TimeClient : public QDialog
{Q_OBJECTpublic:TimeClient(QWidget *parent = 0);~TimeClient();virtual void timerEvent(QTimerEvent *event);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;int m_timerId;bool startRun;
};#endif // TIMECLIENT_H

main.cpp

#include "timeclient.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);TimeClient w;w.show();return a.exec();
}

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();m_timerId=startTimer(1000);startRun=false;
}void TimeClient::timerEvent(QTimerEvent *event){if(event->timerId()==m_timerId && startRun){getTime();}
}TimeClient::~TimeClient()
{}void TimeClient::enableGetBtn()
{getBtn->setEnabled(!serverNameLineEdit->text().isEmpty()&&!portLineEdit->text().isEmpty());
}void TimeClient::getTime()
{getBtn->setEnabled(false);startRun=true;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);
}

Qt工作笔记-多线程时间服务应用相关推荐

  1. Qt工作笔记-发送端发送Json格式的数据包,接收端解析数据包

    原理以及运行 原理是因为QJsonDocument提供了一个函数toJson 可以直接把Json数据转成QByteArray,这样就可以直接发送数据包,然后再按照常规方法解析即可,本源码中含解析内容, ...

  2. Qt工作笔记-在ListWidget中多线程检索数据

    文件读取技术在此链接中: https://blog.csdn.net/qq78442761/article/details/79807826 在ListWidget中单线程检索数据在此链接中: htt ...

  3. Qt工作笔记-UDP多线程数据处理及发送(简单实例)

    目录 逻辑与运行 源码 逻辑与运行 程序逻辑图如下: 接收端运行截图如下: 客户端接收数据如下: 客户端用的是串口调试工具: 源码 程序结构如下: 源码如下: data.h #ifndef DATA_ ...

  4. C/C++|Qt工作笔记-4种方法判断当前对象(类)名或标识(继承发,typeid法,元对象className()法,Q_CLASSINFO法)

    回想起3个月前,刚刚参加工作也做过类似的笔记,但只有2种方法,估计刚毕业没有什么墨水,经过3个月时间又多了2种方法: 这些方法都可用于RTTI 第一个方法是继承发(C++中很推荐用这个,感觉用这个结构 ...

  5. Qt工作笔记-Qt元对象系统解析【2合1】

    博文转载地址: https://blog.csdn.net/spwper/article/details/51332187 说Qt信号与槽是一个很好机制,不如说Qt的元对象系统很强大.这也是大家讲Qt ...

  6. Qt工作笔记-Qt5中中文编码方面的笔记

    目前在使用国内的数据库和实时库接口. 说句实话,国内的东西与国外的东西比,在用户体验和接口调用上比还是存在很大的距离. 个人喜欢用QString去存储数据.个人感觉QTL比STL开发起来要快点 这里有 ...

  7. Qt工作笔记-使用toVariant().toMap()分割Json文件(666解析法)

    目录 概念 演示过程及源码 概念 今天看到大佬去解析Json文件的代码,简直666,特意记录此笔记,方便以后用得到,肯定会用得到. 演示过程及源码 如下面的这个Json代码,这个是调用face++的h ...

  8. Qt工作笔记-对*QObject::sender()的认识

    今天有个大佬给我说了这个函数: [protected] QObject *QObject::sender() const 简直阔怕: 感觉这个函数有点歪门邪道! 这里有个多线程中的警告,Qt::Dir ...

  9. Qt工作笔记-在Graphics上写文本(QGraphicsSimpleTextItem与QGraphicsTextItem的基本使用)

    查了下文档发现就这2个, 一个是QGraphicsTextItem,另外一个是QGraphicsSimpleTextItem 从官方对QGraphicsTextItem中的描述中可以看到: 这个QGr ...

最新文章

  1. 招青年博士,年薪70-80万,200万以上补贴,直聘博导!苏州大学
  2. 应用PlanAhead进行I/O规划
  3. Android必知必会-Android Studio下配置和使用Lambda
  4. 学了python可以从事什么岗位-学完Python编程可以从事哪些岗位?
  5. Linux上使用shell脚本查看内存情况(超实用)
  6. openssl 使用命令
  7. hdu4266(三维凸包模板题)
  8. mysql create database to_MySQL中CREATE DATABASE和CREATE SCHEMA区别(转)
  9. LeetCode MySQL 1412. 查找成绩处于中游的学生
  10. js字符串的字典序_27. 字符串的排列
  11. ceph rbd 常用命令使用
  12. Python3 下找不到urllib2的问题
  13. 苹果正面临电源芯片短缺问题 可能影响iPhone 12供应
  14. 软件体系结构期末复习题
  15. 什么是QCIF? CIF?2CIF?4CIF?DCIF?
  16. 自然语言处理模型:bert 结构原理解析——attention+transformer(翻译自:Deconstructing BERT)
  17. 高阶组件HOC - 小试牛刀
  18. 代码主题darcula_Intellij idea 中的Darcula主题怎么把颜色改回来?
  19. 抖音“何青绫”金融知识整理(部分)
  20. 【STM32F429的DSP教程】第48章 STM32F429的中值滤波器实现,适合噪声和脉冲过滤(支持逐个数据的实时滤波)

热门文章

  1. 关于“Exchange Server 地址列表服务未能响应”的错误解决方法。
  2. HR怎么从面试中了解程序员的真实水平?需要面试的程序员,注意了!
  3. C++老话题:用指向函数的指针作函数参数
  4. 不仅是人类的shooow
  5. 每人都有两大炸弹的扎金花2012
  6. 基于Nokia S60的游戏开发之一
  7. QQ尾巴病毒的Visual C++实现探讨
  8. 你真的了解Python吗?这篇文章可以让你了解90%,赶紧收藏!
  9. 【互联网大会】微信小程序斩获大奖 马化腾谈小程序开发生态
  10. docker容器cpu高问题排查_干货详解:一文教你如何利用阿里开源工具,排查线上CPU居高问题...