多线程网络时间服务器

项目TimeServer

dialog.h

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:dialog.h 
  5. * 时间:2015年2月11日22:43:26 
  6. * 作者:cutter_point 
  7. */  
  8. #ifndef DIALOG_H  
  9. #define DIALOG_H  
  10.   
  11. #include <QDialog>  
  12. #include <QLabel>  
  13. #include <QPushButton>  
  14.   
  15. class TimeServer;  
  16.   
  17. class Dialog : public QDialog  
  18. {  
  19.   Q_OBJECT  
  20.   
  21. public:  
  22.   Dialog(QWidget *parent = 0);  
  23.   ~Dialog();  
  24.   
  25. public slots:  
  26.   void slotShow();    //线程在界面的显示  
  27.   
  28. private:  
  29.   //对应的一些界面控件  
  30.   QLabel *Label1;  
  31.   QLabel *Label2;  
  32.   QPushButton *quitBtn;  
  33.   TimeServer *timeServer;   //每个界面有一个私有时间线程  
  34.   int count;    //计数  
  35. };  
  36.   
  37. #endif // DIALOG_H  


dialog.cpp

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:dialog.cpp 
  5. * 时间:2015年2月11日22:43:26 
  6. * 作者:cutter_point 
  7. */  
  8. #include "dialog.h"  
  9. #include "timeserver.h"  
  10.   
  11. #include <QHBoxLayout>  
  12. #include <QVBoxLayout>  
  13. #include <QMessageBox>  
  14.   
  15. Dialog::Dialog(QWidget *parent)  
  16.   : QDialog(parent)  
  17. {  
  18.   this->setWindowTitle(tr("多线程时间服务器"));  
  19.   
  20.   Label1 = new QLabel(tr("服务器端口:"));  
  21.   Label2 = new QLabel;  
  22.   
  23.   quitBtn = new QPushButton(tr("close"));  
  24.   QHBoxLayout *BtnLayout = new QHBoxLayout;   //这个是横向的布局  
  25.   BtnLayout->addStretch(1);   //一个弹簧  
  26.   BtnLayout->addWidget(quitBtn);  
  27.   BtnLayout->addStretch(1);   //一个弹簧  
  28.   
  29.   QVBoxLayout *mainLayout = new QVBoxLayout(this);    //列的方向  
  30.   mainLayout->addWidget(Label1);  
  31.   mainLayout->addWidget(Label2);  
  32.   mainLayout->addLayout(BtnLayout);  
  33.   
  34.   connect(quitBtn, SIGNAL(clicked()), this, SLOT(close()));  
  35.   
  36.   //有一个计数器  
  37.   count = 0;  
  38.   //创建一个时间服务器  
  39.   timeServer = new TimeServer(this);  
  40.   //监听所有的时间服务器的端口和地址  
  41.   //监听失败的话  
  42.   if(!timeServer->listen())  
  43.     {  
  44.       QMessageBox::critical(this, tr("多线程时间服务器"), tr("无法启动服务器:%1.").arg(timeServer->errorString()));  
  45.       close();  
  46.       return;  
  47.     }  
  48.   
  49.   
  50.   //监听成功,输出有动静的端口号  
  51.   Label1->setText(tr("服务器端口:   %1").arg(timeServer->serverPort()));  
  52. }  
  53.   
  54. //void slotShow();    //线程在界面的显示,线程结束的时候调用  
  55. void Dialog::slotShow()  
  56. {  
  57.   //显示这是第几次请求,也就是第几次调用线程执行这个函数  
  58.   Label2->setText(tr("第%1次请求完毕.").arg(++count));  
  59. }  
  60.   
  61. Dialog::~Dialog()  
  62. {  
  63.   
  64. }  


timeserver.h

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timeserver.h 
  5. * 时间:2015年2月11日23:17:43 
  6. * 作者:cutter_point 
  7. */  
  8. #ifndef TIMESERVER_H  
  9. #define TIMESERVER_H  
  10.   
  11. #include <QTcpServer>  
  12.   
  13. class Dialog;  
  14.   
  15. class TimeServer : public QTcpServer  
  16. {  
  17.   Q_OBJECT  
  18. public:  
  19.   explicit TimeServer(QObject *parent = 0);  
  20.   
  21. signals:  
  22.   
  23. public slots:  
  24.   
  25. protected:  
  26.   void incomingConnection(int socketDescriptor);    //当tcp有新的连接的时候调用,其参数为所接收新连接的套接字描述符  
  27.   
  28. private:  
  29.   Dialog *dlg;    //界面  
  30.   
  31. };  
  32.   
  33. #endif // TIMESERVER_H  


timeserver.cpp

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timeserver.cpp 
  5. * 时间:2015年2月11日23:18:08 
  6. * 作者:cutter_point 
  7. */  
  8. #include "timeserver.h"  
  9. #include "timethread.h"  
  10. #include "dialog.h"  
  11.   
  12. TimeServer::TimeServer(QObject *parent) :  
  13.   QTcpServer(parent)  
  14. {  
  15.   //初始化界面  
  16.   dlg = (Dialog *)parent; //转化为dialog前面的对象的指针  
  17. }  
  18.   
  19. //void incomingConnection(int socketDescriptor);    //当tcp有新的连接的时候调用,其参数为所接收新连接的套接字描述符  
  20. void TimeServer::incomingConnection(int socketDescriptor)  
  21. {  
  22.   //有一个新连接的时候,就相应的创建一个对应的线程  
  23.   TimeThread *thread = new TimeThread(socketDescriptor);  
  24.   
  25.   //线程结束的时候,要通知界面的显示  
  26.   connect(thread, SIGNAL(finished()), dlg, SLOT(slotShow()));  
  27.   //同时销毁结束线程  
  28.   connect(thread, SIGNAL(finished()), dlg, SLOT(deleteLater()));  
  29.   
  30.   //启动线程  
  31.   thread->start();  
  32. }  


timethread.h


[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timethread.h 
  5. * 时间:2015年2月11日22:43:26 
  6. * 作者:cutter_point 
  7. */  
  8. #ifndef TIMETHREAD_H  
  9. #define TIMETHREAD_H  
  10.   
  11. #include <QThread>  
  12. #include <QtNetwork>  
  13. #include <QTcpSocket>  
  14.   
  15. class TimeThread : public QThread  
  16. {  
  17.   Q_OBJECT  
  18. public:  
  19.   explicit TimeThread(int socketDescriptor, QObject *parent = 0);  
  20.   void run();   //继承来的,线程执行的内容  
  21.   
  22. signals:  
  23.   //如果出错的话可以给出错误信息  
  24.   void error(QTcpSocket::SocketError socketError);  
  25.   
  26. public slots:  
  27.   
  28. private:  
  29.   int socketDescriptor;   //套接字描述符  
  30.   
  31.   
  32. };  
  33.   
  34. #endif // TIMETHREAD_H  

timethread.cpp

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timethread.cpp 
  5. * 时间:2015年2月11日22:43:26 
  6. * 作者:cutter_point 
  7. */  
  8. #include "timethread.h"  
  9.   
  10. #include <QDateTime>    //时间  
  11. #include <QByteArray>   //协议传输的字节流  
  12. #include <QDataStream>    //数据流  
  13.   
  14. TimeThread::TimeThread(int socketDescriptor, QObject *parent) :  
  15.   QThread(parent), socketDescriptor(socketDescriptor)     //初始化  
  16. {  
  17. }  
  18.   
  19. void TimeThread::run()    //线程执行开始的函数  
  20. {  
  21.   QTcpSocket tcpSocket;     //创建一个tcp套接字  
  22.   if(!tcpSocket.setSocketDescriptor(socketDescriptor))    //如果套接字描述符操作失败  
  23.     {  
  24.       emit error(tcpSocket.error());    //发出错误信号  
  25.       return;   //结束  
  26.     }  
  27.   
  28.   QByteArray block;   //字节数组,这个block应该是一个指向第一个位置的指针  
  29.   QDataStream out(&block, QIODevice::WriteOnly);    //数据流,数据流操作block,这里block指针??  
  30.   out.setVersion(QDataStream::Qt_5_3);    //版本= =  
  31.   
  32.   uint time2u = QDateTime::currentDateTime().toTime_t();    //得到系统的时间,并传换成时间的格式  
  33.   out<<time2u;    //输入到字节流中  
  34.   
  35.   tcpSocket.write(block);   //把字节流写到协议端口  
  36.   tcpSocket.disconnectFromHost();   //断开端口连接  
  37.   tcpSocket.waitForDisconnected();    //默认时间,等待客户端返回信息  
  38.   
  39. }  


项目TimeClient


timeclient.h

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timeclient.h 
  5. * 时间:2015年2月11日23:49:56 
  6. * 作者:cutter_point 
  7. */  
  8. #ifndef TIMECLIENT_H  
  9. #define TIMECLIENT_H  
  10.   
  11. #include <QDialog>  
  12. #include <QLabel>  
  13. #include <QLineEdit>  
  14. #include <QPushButton>  
  15. #include <QDateTimeEdit>  
  16. #include <QTcpSocket>  
  17. #include <QAbstractSocket>  
  18.   
  19. class TimeClient : public QDialog  
  20. {  
  21.   Q_OBJECT  
  22.   
  23. public:  
  24.   TimeClient(QWidget *parent = 0);  
  25.   ~TimeClient();  
  26. public slots:  
  27.     void enableGetBtn();    //按钮的控制  
  28.     void getTime();   //准备得到时间  
  29.     void readTime();    //读取时间过来  
  30.     void showError(QAbstractSocket::SocketError socketError);   //出错  
  31. private:  
  32.     QLabel *serverNameLabel;  
  33.     QLineEdit *serverNameLineEdit;  
  34.     QLabel *portLabel;  
  35.     QLineEdit *portLineEdit;  
  36.     QDateTimeEdit *dateTimeEdit;    //显示时间的控件  
  37.     QLabel *stateLabel;   //状态表示  
  38.   
  39.     QPushButton *getBtn;  
  40.     QPushButton *quitBtn;  
  41.   
  42.     uint time2u;    //得到的时间  
  43.     QTcpSocket *tcpSocket;      //tcp套接字  
  44. };  
  45.   
  46. #endif // TIMECLIENT_H  


timeclient.cpp

[cpp]  view plain  copy
  1. /** 
  2. * 书本:【Qt5开发及实例】 
  3. * 功能:多线程网络时间服务器 
  4. * 文件:timeclient.cpp 
  5. * 时间:2015年2月11日23:49:56 
  6. * 作者:cutter_point 
  7. */  
  8. #include "timeclient.h"  
  9.   
  10. #include <QHBoxLayout>  
  11. #include <QVBoxLayout>  
  12. #include <QGridLayout>  
  13. #include <QDataStream>  
  14. #include <QMessageBox>  
  15.   
  16. TimeClient::TimeClient(QWidget *parent)  
  17.   : QDialog(parent)  
  18. {  
  19.   setWindowTitle(tr("多线程时间服务客户端"));  
  20.   
  21.   serverNameLabel =new QLabel(tr("服务器名:"));  
  22.   serverNameLineEdit = new QLineEdit("Localhost");  
  23.   
  24.   portLabel =new QLabel(tr("端口:"));  
  25.   portLineEdit = new QLineEdit;  
  26.   
  27.   QGridLayout *layout = new QGridLayout;  
  28.   layout->addWidget(serverNameLabel,0,0);  
  29.   layout->addWidget(serverNameLineEdit,0,1);  
  30.   layout->addWidget(portLabel,1,0);  
  31.   layout->addWidget(portLineEdit,1,1);  
  32.   
  33.   dateTimeEdit = new QDateTimeEdit(this);  
  34.   QHBoxLayout *layout1 = new QHBoxLayout;  
  35.   layout1->addWidget(dateTimeEdit);  
  36.   
  37.   stateLabel =new QLabel(tr("请首先运行时间服务器!"));  
  38.   QHBoxLayout *layout2 = new QHBoxLayout;  
  39.   layout2->addWidget(stateLabel);  
  40.   
  41.   getBtn = new QPushButton(tr("获取时间"));  
  42.   getBtn->setDefault(true);  
  43.   getBtn->setEnabled(false);  
  44.   quitBtn = new QPushButton(tr("close"));  
  45.   QHBoxLayout *layout3 = new QHBoxLayout;  
  46.   layout3->addStretch();  
  47.   layout3->addWidget(getBtn);  
  48.   layout3->addWidget(quitBtn);  
  49.   
  50.   QVBoxLayout *mainLayout = new QVBoxLayout(this);  
  51.   mainLayout->addLayout(layout);  
  52.   mainLayout->addLayout(layout1);  
  53.   mainLayout->addLayout(layout2);  
  54.   mainLayout->addLayout(layout3);  
  55.   
  56.   connect(serverNameLineEdit,SIGNAL(textChanged(QString)),this,SLOT(enableGetBtn()));  
  57.   connect(portLineEdit,SIGNAL(textChanged(QString)),this,SLOT(enableGetBtn()));  
  58.   connect(getBtn,SIGNAL(clicked()),this,SLOT(getTime()));   //准备好接受服务器数据的最北  
  59.   connect(quitBtn,SIGNAL(clicked()),this,SLOT(close()));  
  60.   
  61.   tcpSocket = new QTcpSocket(this);  
  62.   connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readTime()));    //从端口中得到数据  
  63.   connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(showError(QAbstractSocket::SocketError)));  
  64.   
  65.   portLineEdit->setFocus();   //键盘焦点对准这个控件  
  66. }  
  67.   
  68. //void enableGetBtn();    //按钮的控制  
  69. void TimeClient::enableGetBtn()  
  70. {  
  71.   getBtn->setEnabled(!serverNameLineEdit->text().isEmpty()&&!portLineEdit->text().isEmpty());  
  72. }  
  73.   
  74. //void getTime();   //准备得到时间  
  75. void TimeClient::getTime()  
  76. {  
  77.   //得到时间之前,按下了按钮就不能再按了  
  78.   getBtn->setEnabled(false);  
  79.   //初始化这边的时间和套接字,等会用来接收数据  
  80.   time2u = 0;  
  81.   tcpSocket->abort();  //重置套接字
  82.   //连接上相应的服务器和端口,准备连接  
  83.   tcpSocket->connectToHost(serverNameLineEdit->text(), portLineEdit->text().toInt());  
  84. }  
  85.   
  86. //void readTime();    //读取时间过来  
  87. void TimeClient::readTime()  
  88. {  
  89.   //获得到了数据就读取  
  90.   //初始化一个数据流,对端口的套接字操作  
  91.   QDataStream in(tcpSocket);  
  92.   in.setVersion(QDataStream::Qt_5_3);   //版本!!!!  
  93.   //时间如果开始初始化为0了,那么就重新获取  
  94.   if(time2u == 0)  
  95.     {  
  96.       if(tcpSocket->bytesAvailable() < (int)sizeof(uint))  
  97.         return;   //得到的数据不和常理的话,直接结束  
  98.   
  99.       in>>time2u;   //把数据输出到time2u中  
  100.     }  
  101.   //不为零,那么就继续用  
  102.   dateTimeEdit->setDateTime(QDateTime::fromTime_t(time2u));  
  103.   //按钮设置为可以按  
  104.   getBtn->setEnabled(true);  
  105. }  
  106.   
  107. //void showError(QAbstractSocket::SocketError socketError);   //出错  
  108. void TimeClient::showError(QAbstractSocket::SocketError socketError)  
  109. {  
  110.   switch(socketError)  
  111.     {  
  112.     case QAbstractSocket::RemoteHostClosedError:  
  113.             break;  
  114.     case QAbstractSocket::HostNotFoundError:  
  115.          QMessageBox::information(this, tr("时间服务客户端:"),tr("主机不可达!"));  
  116.          break;  
  117.     case QAbstractSocket::ConnectionRefusedError:  
  118.          QMessageBox::information(this, tr("时间服务客户端:"),tr("连接被拒绝!"));  
  119.          break;  
  120.     default:  
  121.         QMessageBox::information(this, tr("时间服务客户端:"),tr("产生如下错误: %1.").arg(tcpSocket->errorString()));  
  122.     }  
  123.   getBtn->setEnabled(true);  
  124. }  
  125.   
  126. TimeClient::~TimeClient()  
  127. {  
  128.   
  129. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值