zoukankan      html  css  js  c++  java
  • C++ Qt多线程 TcpSocket服务器实例

    服务器:
    incomming
    incomming.pro
    #-------------------------------------------------
    #
    # Project created by QtCreator 2016-04-08T09:25:22
    #
    #-------------------------------------------------
    
    
    QT       += core gui
    QT        +=network
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    
    TARGET = incomming
    TEMPLATE = app
    
    
    
    
    SOURCES += main.cpp
            mainwindow.cpp 
        myserver.cpp 
        socketthread.cpp 
        mytcpsocket.cpp
    
    
    HEADERS  += mainwindow.h 
        myserver.h 
        socketthread.h 
        mytcpsocket.h
    
    
    FORMS    += mainwindow.ui
    
    
    
    
    mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    
    #include <QMainWindow>
    class QTcpSocket;
    class myserver;
    namespace Ui {
    class MainWindow;
    }
    
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    private:
      myserver * server;
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    
    private:
        Ui::MainWindow *ui;
    };
    
    
    #endif // MAINWINDOW_H
    
    
    
    myserver.h
    #ifndef MYSERVER
    #define MYSERVER
    #include<QObject>
    #include<QTcpServer>
    #include<QWidget>
    class myserver :public QTcpServer{
        Q_OBJECT
    public:
        myserver(QWidget * parent);
    protected:
        virtual void incomingConnection(qintptr socketDescriptor);
    
    
    };
    //|定义的结束 必须加;
    #endif // MYSERVER
    
    
    
    
    mytcpsocket.h
    #ifndef MYTCPSOCKET
    #define MYTCPSOCKET
    #include<QTcpSocket>
    
    
    class mytcpsocket :public QTcpSocket
    {
        Q_OBJECT
    public:
        mytcpsocket(QWidget * parent,qintptr p);
    private slots:
        void on_discon();
    
    
    public:
        void on_connected();
    
    
    };
    #endif // MYTCPSOCKET
    
    
    
    
    socketthread.h
    
    
    #ifndef SOCKETTHREAD
    #define SOCKETTHREAD
    #include<QThread>
    #include<QTcpSocket>
    #include<QWidget>
    class mytcpsocket;
    class socketThread :public QThread
    {
    private:
        qintptr ptr;
        mytcpsocket * socket;
    public:
        socketThread(QWidget * parent,qintptr p);
    protected:
        virtual void run();
    
    
    
    
    };
    #endif // SOCKETTHREAD
    
    
    
    
    mainwindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include"myserver.h"
    #include<QHostAddress>
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        this->server=new myserver(this);
        this->server->listen(QHostAddress::LocalHost,520);
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    myserver.cpp
    #include"myserver.h"
    #include<QMessageBox>
    #include"mytcpsocket.h"
    #include"socketthread.h"
    myserver::myserver(QWidget * parent):QTcpServer(parent){
    
    
    }
    void myserver::incomingConnection(qintptr socketDescriptor)
    {
        QMessageBox::about(0,"提示","有新连接");
         socketThread * thread=new socketThread(0,socketDescriptor);
        thread->start();
    
    
        /*
        mytcpsocket * socket=new mytcpsocket(0,socketDescriptor);
        QThread * thread=new QThread();
        socket->moveToThread(thread);
        thread->start();
        */
    
    
    
    
    }
    
    
    mytcpsocket.cpp
    #include"mytcpsocket.h"
    #include<QByteArray>
    #include<QDataStream>
    #include<QString>
    #include<QMessageBox>
    #include<QDebug>
    mytcpsocket::mytcpsocket(QWidget *parent,qintptr p):QTcpSocket(0)
    {
    
    
      //connect(this,SIGNAL(),this,SLOT(on_connected()));
        this->setSocketDescriptor(p);
        this->on_connected();
     this->connect(this,SIGNAL(disconnected()),this,SLOT(on_discon()));
    
    
    }
    void mytcpsocket::on_connected()
    {
    
    
        QByteArray arr;
        QDataStream dts(&arr,QIODevice::WriteOnly);
        dts<<QString("这是数据");
        this->write(arr);
        //QMessageBox::about(0,"x","发送成功!");
        qDebug()<<"发送成功";
    
    
    }
    void mytcpsocket::on_discon()
    {
        qDebug()<<"有一个客户端断开!";
    }
    
    
    socketthread.cpp
    #include"socketthread.h"
    #include<QString>
    #include<QByteArray>
    #include<QDataStream>
    #include<QMessageBox>
    #include<QDebug>
    #include"mytcpsocket.h"
    socketThread::socketThread(QWidget *parent,qintptr p):QThread(parent)
    {
    
    
        qDebug()<<"QThread构造函数依然在 旧线程";
        this->ptr=p;
    }
    
    
    void socketThread::run(){
    
    
        /*1.QObject->moveToThread(Thread *)会把一个Qt对象移动到一个新线程中运行 默认在run()中调用了 exec()这样 run()执行完后不会
         * 直接关闭 线程 还会让它 进入消息循环 直到调用了 结束 槽
         * 2.QtcpSocket 的write()函数是异步的 也就是 调用了 后不会立即 发送数据,它会直接往下执行 直到run()的尾部,如果run()没有
         * 调用exec()进行消息循环等待,那么 这个线程 直接就结束了,不会再发送。(发送数据失败)
         *3.如果在run()中调用了 exec()(发送成功)
         *4.如果在 write(QByteArray);后面加一句 socket->waitForBytesWritten();这里就会阻塞等待 直到数据开始发送,这样
         * 不需要exec()在 线程结束之前直接就发送完了
         *socket->waitForConnected()
         * socket->waitForDisconnected()
         * socket->waitForReadyRead()都是一个道理
         */
        qDebug()<<"开始新线程";
       /* QTcpSocket * socket=new QTcpSocket();
        socket->setSocketDescriptor(this->ptr);
    
    
        QByteArray arr;
        QDataStream dts(&arr,QIODevice::WriteOnly);
        dts<<QString("这是数据");
        socket->write(arr);
        */
        mytcpsocket * socket=new mytcpsocket(0,this->ptr);
        socket->waitForBytesWritten();
      // this->exec();
        /*
    1.  连接服务器
    m_tcpSocket->connectToHost("127.0.0.1", 9877);
    connected = m_tcpSocket->waitForConnected();
    只有使用waitForConnected()后,QTcpSocket才真正尝试连接服务器,并返回是否连接的结果。
    
    
    2. 写数据
    m_tcpSocket->write(str.toStdString().c_str(), strlen(str.toStdString().c_str()));
    m_tcpSocket->waitForBytesWritten();
    当使用waitForBytesWritten()后,QTcpSocket才真正发送数据。
    m_tcpSocket->write(str1.toStdString().c_str(), strlen(str1.toStdString().c_str()));
    m_tcpSocket->write(str2.toStdString().c_str(), strlen(str2.toStdString().c_str()));
    的结果是发送了str1str2
    
    
    3. 断开与服务器的连接
    m_tcpSocket->disconnectFromHost()
    m_tcpSocket->waitForDisconnected()
    
    
    4. 善于使用QTcpSocket的SIGNAL:connected(), disconnected(), error(QAbstractSocket::SocketError)
        配合自定义私有开关变量bool connected, QTimer
       可以实现自动重连接等逻辑。
    
    
          */
    }
    
    
    main.cpp
    #include "mainwindow.h"
    #include <QApplication>
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
    
        return a.exec();
    }
    
    
    
    
    
    
    
    
    
    
    
    
    /***********************/
    
    
    
    
    
    
    
    
    
    
    客户端
    useincomming
    useincomming.pro
    #-------------------------------------------------
    #
    # Project created by QtCreator 2016-04-08T09:36:28
    #
    #-------------------------------------------------
    
    
    QT       += core gui
    QT       +=network
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    
    TARGET = useincomming
    TEMPLATE = app
    
    
    
    
    SOURCES += main.cpp
            mainwindow.cpp
    
    
    HEADERS  += mainwindow.h
    
    
    FORMS    += mainwindow.ui
    
    
    mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    
    #include <QMainWindow>
    class QTcpSocket;
    namespace Ui {
    class MainWindow;
    }
    
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    private:
        QTcpSocket * socket;
    private:
        Ui::MainWindow *ui;
    private slots:
        void on_readyread();
        void on_conn();
    };
    
    
    #endif // MAINWINDOW_H
    
    
    mainwindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QTcpSocket>
    #include<QHostAddress>
    #include<QString>
    #include<QByteArray>
    #include<QDataStream>
    #include<QMessageBox>
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        this->socket=new QTcpSocket(this);
        this->socket->connectToHost(QHostAddress::LocalHost,520);
        connect(this->socket,SIGNAL(connected()),this,SLOT(on_conn()));
        connect(this->socket,SIGNAL(readyRead()),this,SLOT(on_readyread()));
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    void MainWindow::on_readyread()
    {
        QMessageBox::about(this,"提示","开始接受");
        QByteArray array=this->socket->readAll();
        QDataStream dts(&array,QIODevice::ReadOnly);
        QString data;
        dts>>data;
        QMessageBox::about(this,"提示",data);
    
    
    }
    void MainWindow::on_conn()
    {
        QMessageBox::about(this,"提示","连接成功");
    }
    
    
    main.cpp
    #include "mainwindow.h"
    #include <QApplication>
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
    
        return a.exec();
    }
    
  • 相关阅读:
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
  • 原文地址:https://www.cnblogs.com/wlzy/p/6801875.html
Copyright © 2011-2022 走看看