通过QTcpServer从服务端获取时间

效果图
通过QTcpServer从服务端获取时间_第1张图片
通过QTcpServer从服务端获取时间_第2张图片
服务端
注意: 在.pro中加入QT += network
dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 
class TimeServer;
class Dialog : public QDialog
{
    Q_OBJECT

public:
    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 
#include 
#include 
#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));
}

timeserver.h

#ifndef TIMESERVER_H
#define TIMESERVER_H

#include 
class Dialog;                         //服务器端的声明
class TimeServer : public QTcpServer
{
    Q_OBJECT
public:
    TimeServer(QObject *parent=0);
protected:
    void incomingConnection(int socketDescriptor);//将要连接
private:
    Dialog *dlg;
};

#endif // TIMESERVER_H

timesetver.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();//执行run()
}

timethread.h

#ifndef TIMETHREAD_H
#define TIMETHREAD_H

#include 
#include 
#include 

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

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中
    tcpSocket.write(block);
    tcpSocket.disconnectFromHost();//断开连接
    tcpSocket.waitForDisconnected();
}

客户端
注意: 在.pro中加入QT += network
timeclient.h

#ifndef TIMECLIENT_H
#define TIMECLIENT_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

class TimeClient : public QDialog
{
    Q_OBJECT

public:
    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

timeclinet.cpp

#include "timeclient.h"
#include 
#include 
#include 
#include 
#include 

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

你可能感兴趣的:(初学者)