分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
[cpp] view plain copy
- 服务器:
- 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();
- }