zoukankan      html  css  js  c++  java
  • Qt 基于TCP的Socket编程

    1、在工程文件中加入QT += network

    2、服务器除了使用到了QTcpSocket类,还需要用到QTcpSever类

    (1)创建QTcpSever对象

    tcpServer = new QTcpServer(this);  

    2)监听端口

    tcpServer->listen(QHostAddress::LocalHost, 30000)  

    (3) 当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问

    connect(tcpServer, &QTcpServer::newConnection,  
                this, &MainWindow::sendMessage);  

    4)获取客户端连接

    // 获取已经建立的连接的套接字  
    clientConnection = tcpServer->nextPendingConnection();  
    QObject::connect(clientConnection, &QTcpSocket::readyRead, this, &MainWindow::readMessage); 

    (5)发数据

     1 // 用于暂存要发送的数据  
     2     QByteArray block;  
     3     QDataStream out(&block, QIODevice::WriteOnly);  
     4   
     5     // 设置数据流的版本,客户端和服务器端使用的版本要相同  
     6     out.setVersion(QDataStream::Qt_5_6);  
     7     out << (quint16)0;  
     8     out << tr("connect sucessful !");  
     9     out.device()->seek(0);  
    10     out << (quint16)(block.size() - sizeof(quint16));  
    11   
    12     clientConnection->write(block);  
    13     clientConnection->flush(); 

    (6)读数据

    1 QDataStream in(clientConnection);  
    2   
    3     // 设置数据流版本,这里要和服务器端相同  
    4     in.setVersion(QDataStream::Qt_5_6);  
    5   
    6     in >> blockSize;  
    7     in >> message;  

    3、客户端

    (1)创建QTcpSocket套接字对象

    tcpSocket = new QTcpSocket(this);  

    (2)使用这个对象连接服务器

    server->listen(QHostAddress::Any, port)  

    (3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问

    1 connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);  
    2   
    3 void MainWindow::server_New_Connect()  
    4 {  
    5     //获取客户端连接  
    6     socket = server->nextPendingConnection();  
    7 }  

    代码:

    客户端

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3  
     4 #include <QMainWindow>
     5 #include <QAbstractSocket>
     6 class QTcpSocket;
     7  
     8 namespace Ui {
     9 class MainWindow;
    10 }
    11  
    12 class MainWindow : public QMainWindow
    13 {
    14     Q_OBJECT
    15  
    16 public:
    17     explicit MainWindow(QWidget *parent = 0);
    18     ~MainWindow();
    19  
    20 private:
    21     QList<QString> DataList;
    22     Ui::MainWindow *ui;
    23     QTcpSocket *tcpSocket;
    24     QString message;
    25     // 用来存放数据的大小信息
    26     quint16 blockSize;
    27  
    28 private slots:
    29     void newConnect();
    30     void readMessage();
    31     void displayError(QAbstractSocket::SocketError);
    32  
    33     void on_ConPushButton_clicked();
    34     void on_SendPushButton_clicked();
    35     void on_disConPushButton_clicked();
    36     void on_SeeDatabtn_clicked();
    37     void on_ClearBtn_clicked();
    38 };
    39  
    40 #endif // MAINWINDOW_H
      1 #include "mainwindow.h"
      2 #include "ui_mainwindow.h"
      3 #include <QtNetwork>
      4  
      5 MainWindow::MainWindow(QWidget *parent) :
      6     QMainWindow(parent),
      7     ui(new Ui::MainWindow)
      8 {
      9     ui->setupUi(this);
     10     ui->hostLineEdit->setText("127.0.0.1");
     11     ui->portLineEdit->setText("30000");
     12     tcpSocket = new QTcpSocket(this);
     13  
     14     connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::readMessage);
     15     connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
     16             this, SLOT(displayError(QAbstractSocket::SocketError)));
     17 }
     18  
     19 MainWindow::~MainWindow()
     20 {
     21     delete ui;
     22 }
     23  
     24 void MainWindow::newConnect(){
     25     // 初始化数据大小信息为0
     26     blockSize = 0;
     27  
     28     // 取消已有的连接
     29     tcpSocket->abort();
     30     tcpSocket->connectToHost(ui->hostLineEdit->text(),
     31                              ui->portLineEdit->text().toInt());
     32     ui->conn_state->setText("已连接");
     33 }
     34  
     35 void MainWindow::readMessage(){
     36     QDataStream in(tcpSocket);
     37  
     38     // 设置数据流版本,这里要和服务器端相同
     39     in.setVersion(QDataStream::Qt_5_6);
     40  
     41  
     42     in >> blockSize;
     43     // 将接收到的数据存放到变量中
     44     in >> message;
     45     // 显示接收到的数据
     46     ui->MessageAccept->setText(message);
     47     if(message != "connect sucessful !"){
     48         DataList.append(message);
     49     }
     50 }
     51  
     52  
     53  
     54 void MainWindow::displayError(QAbstractSocket::SocketError)
     55 {
     56     qDebug() << tcpSocket->errorString();
     57     ui->conn_state->setText("连接发生错误!请重新连接。");
     58 }
     59  
     60 void MainWindow::on_ConPushButton_clicked()
     61 {
     62     newConnect();
     63 }
     64  
     65 void MainWindow::on_SendPushButton_clicked()
     66 {
     67     // 用于暂存要发送的数据
     68     QByteArray block;
     69     QDataStream out(&block, QIODevice::WriteOnly);
     70  
     71     // 设置数据流的版本,客户端和服务器端使用的版本要相同
     72     out.setVersion(QDataStream::Qt_5_6);
     73     out << (quint16)0;
     74     out << ui->MesslineEdit->text();
     75     out.device()->seek(0);
     76     out << (quint16)(block.size() - sizeof(quint16));
     77  
     78     tcpSocket->write(block);
     79     tcpSocket->flush();
     80 }
     81  
     82 void MainWindow::on_disConPushButton_clicked()
     83 {
     84     tcpSocket->disconnectFromHost();
     85     ui->conn_state->setText("未连接");
     86 }
     87  
     88 //查看接收数据
     89 void MainWindow::on_SeeDatabtn_clicked()
     90 {
     91     for(int i=0;i<DataList.size();i++){
     92         qDebug() << DataList.at(i);
     93     }
     94 }
     95  
     96 //清空接收数据
     97 void MainWindow::on_ClearBtn_clicked()
     98 {
     99     DataList.clear();
    100 }

    服务器端

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3  
     4 #include <QMainWindow>
     5 #include <QtNetwork>
     6 class QTcpServer;
     7  
     8 namespace Ui {
     9 class MainWindow;
    10 }
    11  
    12 class MainWindow : public QMainWindow
    13 {
    14     Q_OBJECT
    15  
    16 public:
    17     explicit MainWindow(QWidget *parent = 0);
    18     ~MainWindow();
    19  
    20 private:
    21     Ui::MainWindow *ui;
    22     QTcpServer *tcpServer;
    23     QTcpSocket *clientConnection;
    24     QString message;
    25     // 用来存放数据的大小信息
    26     quint16 blockSize;
    27     QTimer *timer;
    28  
    29 private slots:
    30     //void acceptMessage();
    31     void sendMessage();
    32     void readMessage();
    33  
    34     void displayError(QAbstractSocket::SocketError);
    35     void on_send_clicked();
    36  
    37     void timerSendMess();
    38 };
    39  
    40 #endif // MAINWINDOW_H
      1 #include "mainwindow.h"
      2 #include "ui_mainwindow.h"
      3 #include <QtNetwork>
      4 #include <QTime>
      5 #include <QTimer>
      6  
      7 MainWindow::MainWindow(QWidget *parent) :
      8     QMainWindow(parent),
      9     ui(new Ui::MainWindow)
     10 {
     11     ui->setupUi(this);
     12  
     13     tcpServer = new QTcpServer(this);
     14     if((!tcpServer->listen(QHostAddress::LocalHost, 30000))){
     15         qDebug() << tcpServer->errorString();
     16         close();
     17     }
     18     connect(tcpServer, &QTcpServer::newConnection,
     19             this, &MainWindow::sendMessage);
     20  
     21     //定时器
     22     timer = new QTimer(this);
     23     connect(timer,&QTimer::timeout,this,&MainWindow::timerSendMess);
     24  
     25 }
     26  
     27 MainWindow::~MainWindow()
     28 {
     29     clientConnection->close();
     30     delete ui;
     31 }
     32  
     33 //定时发送数据
     34 void MainWindow::timerSendMess(){
     35     int rand = qrand() % 30000;
     36     ui->MessSend->setText(QString::number(rand, 10));
     37  
     38     // 用于暂存要发送的数据
     39     QByteArray block;
     40     QDataStream out(&block, QIODevice::WriteOnly);
     41  
     42     // 设置数据流的版本,客户端和服务器端使用的版本要相同
     43     out.setVersion(QDataStream::Qt_5_6);
     44     out << (quint16)0;
     45     out << QString::number(rand, 10);
     46     out.device()->seek(0);
     47     out << (quint16)(block.size() - sizeof(quint16));
     48  
     49     clientConnection->write(block);
     50     clientConnection->flush();
     51 }
     52  
     53 void MainWindow::sendMessage(){
     54  
     55     // 获取已经建立的连接的套接字
     56     clientConnection = tcpServer->nextPendingConnection();
     57     QObject::connect(clientConnection, &QTcpSocket::readyRead, this, &MainWindow::readMessage);
     58     connect(clientConnection, SIGNAL(error(QAbstractSocket::SocketError)),
     59             this, SLOT(displayError(QAbstractSocket::SocketError)));
     60  
     61     // 用于暂存要发送的数据
     62     QByteArray block;
     63     QDataStream out(&block, QIODevice::WriteOnly);
     64  
     65     // 设置数据流的版本,客户端和服务器端使用的版本要相同
     66     out.setVersion(QDataStream::Qt_5_6);
     67     out << (quint16)0;
     68     out << tr("connect sucessful !");
     69     out.device()->seek(0);
     70     out << (quint16)(block.size() - sizeof(quint16));
     71  
     72     clientConnection->write(block);
     73     clientConnection->flush();
     74  
     75     ui->waitconn->setText(tr("连接成功!"));
     76 }
     77  
     78 void MainWindow::on_send_clicked()
     79 {
     80     // 用于暂存要发送的数据
     81     QByteArray block;
     82     QDataStream out(&block, QIODevice::WriteOnly);
     83  
     84     // 设置数据流的版本,客户端和服务器端使用的版本要相同
     85     out.setVersion(QDataStream::Qt_5_6);
     86     out << (quint16)0;
     87     out << ui->MessSend->text();
     88     out.device()->seek(0);
     89     out << (quint16)(block.size() - sizeof(quint16));
     90  
     91     clientConnection->write(block);
     92     clientConnection->flush();
     93 }
     94  
     95 void MainWindow::readMessage(){
     96     QDataStream in(clientConnection);
     97  
     98     // 设置数据流版本,这里要和服务器端相同
     99     in.setVersion(QDataStream::Qt_5_6);
    100  
    101     in >> blockSize;
    102     in >> message;
    103  
    104     //读出内容和大小
    105     qDebug() << blockSize;
    106     qDebug() << message;
    107  
    108     if(message=="ACTION"){
    109         //1s一个数据
    110         timer->start(300);
    111     }
    112     if(message=="STOP"){
    113         timer->stop();
    114     }
    115  
    116     ui->MessAccept->setText(message);
    117 }
    118  
    119 void MainWindow::displayError(QAbstractSocket::SocketError){
    120     qDebug() << clientConnection->errorString();
    121     ui->waitconn->setText("未连接,等待连接");
    122 }

  • 相关阅读:
    CSS margin的一些让你模糊的点
    VUE中CSS样式穿透
    如何给img标签里的请求添加自定义header?
    iframe的父子页面进行简单的相互传值
    Docker部署网站之后映射域名
    机器学习笔记(九)---- 集成学习(ensemble learning)【华为云技术分享】
    鲲鹏性能优化十板斧之前言 | 鲲鹏处理器NUMA简介与性能调优五步法
    【我的物联网成长记8】超速入门AT指令集【华为云技术分享】
    【直播分享】实现LOL小地图英雄头像分析案例【华为云分享】
    MongoDB一次节点宕机引发的思考(源码剖析)【华为云分享】
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14743511.html
Copyright © 2011-2022 走看看