C++ Qt多线程 TcpSocket服务器实例

来源:互联网 发布:遇见交友软件 编辑:程序博客网 时间:2024/05/14 17:38
服务器:incommingincomming.pro#-------------------------------------------------## Project created by QtCreator 2016-04-08T09:25:22##-------------------------------------------------QT       += core guiQT        +=networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = incommingTEMPLATE = appSOURCES += main.cpp\        mainwindow.cpp \    myserver.cpp \    socketthread.cpp \    mytcpsocket.cppHEADERS  += mainwindow.h \    myserver.h \    socketthread.h \    mytcpsocket.hFORMS    += mainwindow.uimainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>class QTcpSocket;class myserver;namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTprivate:  myserver * server;public:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();private:    Ui::MainWindow *ui;};#endif // MAINWINDOW_Hmyserver.h#ifndef MYSERVER#define MYSERVER#include<QObject>#include<QTcpServer>#include<QWidget>class myserver :public QTcpServer{    Q_OBJECTpublic:    myserver(QWidget * parent);protected:    virtual void incomingConnection(qintptr socketDescriptor);};//|定义的结束 必须加;#endif // MYSERVERmytcpsocket.h#ifndef MYTCPSOCKET#define MYTCPSOCKET#include<QTcpSocket>class mytcpsocket :public QTcpSocket{    Q_OBJECTpublic:    mytcpsocket(QWidget * parent,qintptr p);private slots:    void on_discon();public:    void on_connected();};#endif // MYTCPSOCKETsocketthread.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 // SOCKETTHREADmainwindow.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()));的结果是发送了str1str23. 断开与服务器的连接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();}/***********************/客户端useincomminguseincomming.pro#-------------------------------------------------## Project created by QtCreator 2016-04-08T09:36:28##-------------------------------------------------QT       += core guiQT       +=networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = useincommingTEMPLATE = appSOURCES += main.cpp\        mainwindow.cppHEADERS  += mainwindow.hFORMS    += mainwindow.uimainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>class QTcpSocket;namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTpublic:    explicit MainWindow(QWidget *parent = 0);    ~MainWindow();private:    QTcpSocket * socket;private:    Ui::MainWindow *ui;private slots:    void on_readyread();    void on_conn();};#endif // MAINWINDOW_Hmainwindow.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();}

1 0