zoukankan      html  css  js  c++  java
  • QtTcpService与QtTcpClient

    相关资料:

    https://www.cnblogs.com/ybqjymy/p/13683899.html

    https://download.csdn.net/download/zhujianqiangqq/20429592    代码包下载

    服务端实例:

    QtTcpService.pro

     1 QT       += core gui
     2 QT += network
     3 
     4 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
     5 
     6 CONFIG += c++11
     7 
     8 # The following define makes your compiler emit warnings if you use
     9 # any Qt feature that has been marked deprecated (the exact warnings
    10 # depend on your compiler). Please consult the documentation of the
    11 # deprecated API in order to know how to port your code away from it.
    12 DEFINES += QT_DEPRECATED_WARNINGS
    13 
    14 # You can also make your code fail to compile if it uses deprecated APIs.
    15 # In order to do so, uncomment the following line.
    16 # You can also select to disable deprecated APIs only up to a certain version of Qt.
    17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    18 
    19 SOURCES += 
    20     Server.cpp 
    21     TcpClientSocket.cpp 
    22     Tcpserver.cpp 
    23     main.cpp
    24 
    25 HEADERS += 
    26     Server.h 
    27     TcpClientSocket.h 
    28     Tcpserver.h
    29 
    30 FORMS += 
    31     tcpserver.ui
    32 
    33 # Default rules for deployment.
    34 qnx: target.path = /tmp/$${TARGET}/bin
    35 else: unix:!android: target.path = /opt/$${TARGET}/bin
    36 !isEmpty(target.path): INSTALLS += target
    View Code

    main.cpp

     1 #include "Tcpserver.h"
     2 
     3 #include <QApplication>
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     TcpServer w;
     9     w.show();
    10     return a.exec();
    11 }
    View Code

    Tcpserver.h

     1 #ifndef TCPSERVER_H
     2 #define TCPSERVER_H
     3 
     4 #include <QWidget>
     5 #include "Server.h"
     6 
     7 namespace Ui {
     8 class TcpServer;
     9 }
    10 
    11 class TcpServer : public QWidget
    12 {
    13     Q_OBJECT
    14 
    15 public:
    16     explicit TcpServer(QWidget *parent = 0);
    17     ~TcpServer();
    18 
    19 private slots:
    20     void on_CreateChattingRoom_clicked();
    21     void slotupdateserver(QString, int);//接收到server发过来的信号就更新界面的信息
    22 private:
    23     Ui::TcpServer *ui;
    24     int port;
    25     Server *server;
    26 };
    27 
    28 #endif // TCPSERVER_H
    View Code

    Tcpserver.cpp

     1 #include "Tcpserver.h"
     2 #include "ui_tcpserver.h"
     3 
     4 TcpServer::TcpServer(QWidget *parent) :
     5     QWidget(parent),
     6     ui(new Ui::TcpServer)
     7 {
     8     ui->setupUi(this);
     9     port = 8888;
    10 }
    11 
    12 TcpServer::~TcpServer()
    13 {
    14     delete ui;
    15 }
    16 
    17 void TcpServer::slotupdateserver(QString msg, int length)
    18 {
    19     ui->textEdit->append(msg);
    20 }
    21 
    22 void TcpServer::on_CreateChattingRoom_clicked()
    23 {
    24     server  = new Server(this, port);
    25     connect(server, &Server::updateserver, this, &TcpServer::slotupdateserver);
    26     ui->CreateChattingRoom->setEnabled(false);
    27 }
    View Code

    Server.h

     1 #ifndef SERVER_H
     2 #define SERVER_H
     3 
     4 
     5 #include <QTcpServer>
     6 #include <QObject>
     7 #include <QList>
     8 #include "TcpClientSocket.h"
     9 
    10 class Server : public QTcpServer
    11 {
    12     Q_OBJECT //为了实现信号和槽的通信
    13 public:
    14     Server(QObject *parent = 0, int port = 0);
    15     QList<TcpClientSocket*> tcpclientsocketlist;
    16 protected:
    17     void incomingConnection(qintptr socketDescriptor);//只要出现一个新的连接,就会自动调用这个函数
    18 protected slots:
    19     void sliotupdateserver(QString, int);//用来处理tcpclient发过来的信号
    20     void slotclientdisconnect(int);
    21 
    22 signals:
    23     void updateserver(QString, int);//发送信号给界面,让界面更新信息
    24 };
    25 
    26 
    27 #endif // SERVER_H
    View Code

    Server.cpp

     1 #include "Server.h"
     2 #include <QHostAddress>
     3 
     4 Server::Server(QObject *parent, int port):QTcpServer(parent)
     5 {
     6     listen(QHostAddress::Any, port); //监听
     7 }
     8 
     9 void Server::incomingConnection(qintptr socketDescriptor)
    10 {
    11     TcpClientSocket *tcpclientsocket = new TcpClientSocket(this);//只要有新的连接就生成一个新的通信套接字
    12     //将新创建的通信套接字描述符指定为参数socketdescriptor
    13     tcpclientsocket->setSocketDescriptor(socketDescriptor);
    14 
    15     //将这个套接字加入客户端套接字列表中
    16     tcpclientsocketlist.append(tcpclientsocket);
    17 
    18 
    19     //接收到tcpclientsocket发送过来的更新界面的信号
    20     connect(tcpclientsocket, &TcpClientSocket::updateserver, this, &Server::sliotupdateserver);
    21     connect(tcpclientsocket, &TcpClientSocket::clientdisconnected, this, &Server::slotclientdisconnect);
    22 
    23 }
    24 
    25 void Server::sliotupdateserver(QString msg, int length)
    26 {
    27     //将这个信号发送给界面
    28     emit updateserver(msg, length);
    29 
    30     //将收到的信息发送给每个客户端,从套接字列表中找到需要接收的套接字
    31     for(int i = 0; i < tcpclientsocketlist.count(); i++)
    32     {
    33         QTcpSocket *item = tcpclientsocketlist.at(i);
    34 //        if(item->write((char*)msg.toUtf8().data(), length) != length)
    35 //        {
    36 //            continue;
    37 //        }
    38         item->write(msg.toUtf8().data());
    39     }
    40 
    41 }
    42 
    43 void Server::slotclientdisconnect(int descriptor)
    44 {
    45     for(int i = 0; i < tcpclientsocketlist.count(); i++)
    46     {
    47         QTcpSocket *item = tcpclientsocketlist.at(i);
    48         if(item->socketDescriptor() == descriptor)
    49         {
    50             tcpclientsocketlist.removeAt(i);//如果有客户端断开连接, 就将列表中的套接字删除
    51             return;
    52         }
    53     }
    54     return;
    55 }
    View Code

    TcpClientSocket.h

     1 #ifndef TCPCLIENTSOCKET_H
     2 #define TCPCLIENTSOCKET_H
     3 
     4 
     5 #include <QTcpSocket>
     6 
     7 class TcpClientSocket : public QTcpSocket
     8 {
     9     Q_OBJECT //添加这个宏是为了实现信号和槽的通信
    10 public:
    11     TcpClientSocket(QObject *parent = 0);
    12 protected slots:
    13     void receivedata();//处理readyRead信号读取数据
    14     void slotclientdisconnected();//客户端断开连接触发disconnected信号,这个槽函数用来处理这个信号
    15 
    16 signals:
    17     void updateserver(QString, int);//用来告诉tcpserver需要跟新界面的显示
    18     void clientdisconnected(int); //告诉server有客户端断开连接
    19 };
    20 
    21 #endif // TCPCLIENTSOCKET_H
    View Code

    TcpClientSocket.cpp

     1 #include "tcpclientsocket.h"
     2 
     3 TcpClientSocket::TcpClientSocket(QObject *parent)
     4 {
     5     //客户端发送数据过来就会触发readyRead信号
     6     connect(this, &TcpClientSocket::readyRead, this, &TcpClientSocket::receivedata);
     7     connect(this, &TcpClientSocket::disconnected, this, &TcpClientSocket::slotclientdisconnected);
     8 }
     9 
    10 void TcpClientSocket::receivedata()
    11 {
    12 //    while(bytesAvailable() > 0)
    13 //    {
    14 //        int length = bytesAvailable();
    15 //        char buf[1024]; //用来存放获取的数据
    16 //        read(buf, length);
    17 //        QString msg = buf;
    18 //        //发信号给界面,让界面显示登录者的信息
    19 //        emit updateserver(msg, length);
    20 //    }
    21     int length = 10;
    22     QByteArray array = readAll();
    23     QString msg = array;
    24     emit updateserver(msg, length);
    25 }
    26 
    27 void TcpClientSocket::slotclientdisconnected()
    28 {
    29     emit clientdisconnected(this->socketDescriptor());
    30 }
    View Code

    tcpserver.ui

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <ui version="4.0">
     3  <class>TcpServer</class>
     4  <widget class="TcpServer" name="TcpServer">
     5   <property name="geometry">
     6    <rect>
     7     <x>0</x>
     8     <y>0</y>
     9     <width>309</width>
    10     <height>334</height>
    11    </rect>
    12   </property>
    13   <property name="windowTitle">
    14    <string>TcpServer</string>
    15   </property>
    16   <widget class="QLabel" name="label">
    17    <property name="geometry">
    18     <rect>
    19      <x>10</x>
    20      <y>260</y>
    21      <width>271</width>
    22      <height>16</height>
    23     </rect>
    24    </property>
    25    <property name="text">
    26     <string>端口:8888</string>
    27    </property>
    28   </widget>
    29   <widget class="QTextEdit" name="textEdit">
    30    <property name="geometry">
    31     <rect>
    32      <x>10</x>
    33      <y>20</y>
    34      <width>281</width>
    35      <height>231</height>
    36     </rect>
    37    </property>
    38   </widget>
    39   <widget class="QPushButton" name="CreateChattingRoom">
    40    <property name="geometry">
    41     <rect>
    42      <x>10</x>
    43      <y>280</y>
    44      <width>271</width>
    45      <height>23</height>
    46     </rect>
    47    </property>
    48    <property name="text">
    49     <string>创建聊天室</string>
    50    </property>
    51   </widget>
    52  </widget>
    53  <customwidgets>
    54   <customwidget>
    55    <class>TcpServer</class>
    56    <extends>QWidget</extends>
    57    <header>tcpserver.h</header>
    58    <container>1</container>
    59   </customwidget>
    60  </customwidgets>
    61  <resources/>
    62  <connections/>
    63 </ui>
    View Code

    客户端实例:

     QtTcpClient.pro

     1 QT       += core gui
     2 QT += network
     3 
     4 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
     5 
     6 CONFIG += c++11
     7 
     8 # The following define makes your compiler emit warnings if you use
     9 # any Qt feature that has been marked deprecated (the exact warnings
    10 # depend on your compiler). Please consult the documentation of the
    11 # deprecated API in order to know how to port your code away from it.
    12 DEFINES += QT_DEPRECATED_WARNINGS
    13 
    14 # You can also make your code fail to compile if it uses deprecated APIs.
    15 # In order to do so, uncomment the following line.
    16 # You can also select to disable deprecated APIs only up to a certain version of Qt.
    17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    18 
    19 SOURCES += 
    20     TcpClient.cpp 
    21     main.cpp
    22 
    23 HEADERS += 
    24     TcpClient.h
    25 
    26 FORMS += 
    27     TcpClient.ui
    28 
    29 # Default rules for deployment.
    30 qnx: target.path = /tmp/$${TARGET}/bin
    31 else: unix:!android: target.path = /opt/$${TARGET}/bin
    32 !isEmpty(target.path): INSTALLS += target
    View Code

    main.cpp

     1 #include "TcpClient.h"
     2 
     3 #include <QApplication>
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     TcpClient w;
     9     w.show();
    10     return a.exec();
    11 }
    View Code

    TcpClient.h

     1 #ifndef TCPCLIENT_H
     2 #define TCPCLIENT_H
     3 
     4 #include <QWidget>
     5 #include <QTcpSocket>
     6 
     7 namespace Ui {
     8 class TcpClient;
     9 }
    10 
    11 class TcpClient : public QWidget
    12 {
    13     Q_OBJECT
    14 
    15 public:
    16     explicit TcpClient(QWidget *parent = 0);
    17     ~TcpClient();
    18 
    19 private slots:
    20     void on_pushButtonEnter_clicked();
    21     void slotconnectedsuccess();//用来处理连接成功的信号
    22     void slotreceive();//接收服务器传过来的信息
    23     void on_pushButtonSend_clicked();
    24     void slotdisconnected();//用来处理离开聊天室的信号
    25 
    26 
    27 private:
    28     Ui::TcpClient *ui;
    29     bool status;//用来判断是否进入了聊天室
    30     int port;
    31     QHostAddress *serverIP;
    32     QString userName;
    33     QTcpSocket *tcpsocket;
    34 };
    35 
    36 #endif // TCPCLIENT_H
    View Code

    TcpClient.cpp

      1 #include "TcpClient.h"
      2 #include "ui_tcpclient.h"
      3 #include <QHostAddress>
      4 #include <QMessageBox>
      5 
      6 TcpClient::TcpClient(QWidget *parent) :
      7     QWidget(parent),
      8     ui(new Ui::TcpClient)
      9 {
     10     ui->setupUi(this);
     11     //将进入聊天室的标志位置为false
     12     status = false;
     13     //端口为8888
     14     port = 8888;
     15     ui->lineEditServerPort->setText(QString::number(port));//界面中端口默认显示8888
     16 
     17     serverIP = new QHostAddress();
     18 
     19     //未进入聊天室内不能发送信息
     20     ui->pushButtonSend->setEnabled(false);
     21 }
     22 
     23 TcpClient::~TcpClient()
     24 {
     25     delete ui;
     26 }
     27 
     28 //进入聊天室
     29 void TcpClient::on_pushButtonEnter_clicked()
     30 {
     31     //首先判断这个用户是不是在聊天室中
     32     if(status == false)
     33     {
     34         //不在聊天室中就和服务器进行连接
     35         QString ip = ui->lineEditServerIp->text();//从界面获取ip地址
     36         if(!serverIP->setAddress(ip))//用这个函数判断IP地址是否可以被正确解析
     37         {
     38             //不能被正确解析就弹出一个警告窗口
     39             QMessageBox::warning(this, "错误", "IP地址不正确");
     40             return;
     41         }
     42         if(ui->lineEditUserName->text() == "")
     43         {
     44             //用户名不能为空
     45             QMessageBox::warning(this, "错误", "用户名不能为空");
     46             return;
     47         }
     48 
     49         //从界面获取用户名
     50         userName = ui->lineEditUserName->text();
     51         //创建一个通信套接字,用来和服务器进行通信
     52         tcpsocket = new QTcpSocket(this);
     53 
     54         //和服务器进行连接
     55         tcpsocket->connectToHost(*serverIP, port);
     56 
     57         //和服务器连接成功能会触发connected信号
     58         connect(tcpsocket, &QTcpSocket::connected, this, &TcpClient::slotconnectedsuccess);
     59         //接收到服务器的信息就会触发readyRead信号
     60         connect(tcpsocket, &QTcpSocket::readyRead, this, &TcpClient::slotreceive);
     61 
     62 
     63 
     64         //将进入聊天室的标志位置为true;
     65         status = true;
     66     }
     67     else//已经进入了聊天室
     68     {
     69         int length = 0;
     70         QString msg = userName + ":Leave Chat Room";
     71 //        if((length = tcpsocket->write((char*)msg.toUtf8().data(), msg.length())) != msg.length())
     72 //        {
     73 //            return;
     74 //        }
     75         tcpsocket->write(msg.toUtf8().data());
     76         tcpsocket->disconnectFromHost();
     77         status = false;
     78         //离开聊天室就会触发disconnected信号
     79         connect(tcpsocket, &QTcpSocket::disconnected, this, &TcpClient::slotdisconnected);
     80     }
     81 }
     82 
     83 //用来处理连接成功的信号
     84 void TcpClient::slotconnectedsuccess()
     85 {
     86     //进入聊天室可以发送信息了
     87     ui->pushButtonSend->setEnabled(true);
     88     //将进入聊天的按钮改为离开聊天室
     89     ui->pushButtonEnter->setText(QStringLiteral("离开聊天室"));
     90 
     91     int length = 0;
     92     //将用户名发送给服务器
     93     QString msg= userName + " :Enter Chat Room";
     94 
     95 //    if((length = tcpsocket->write((char*)msg.toUtf8().data(), msg.length())) != msg.length())
     96 //    {
     97 //        return;
     98 //    }
     99     tcpsocket->write(msg.toUtf8().data());
    100 }
    101 
    102 
    103 void TcpClient::slotreceive()
    104 {
    105 //    while(tcpsocket->bytesAvailable() > 0 )
    106 //    {
    107 //        QByteArray datagram;
    108 //        datagram.resize(tcpsocket->bytesAvailable());
    109 //        tcpsocket->read(datagram.data(), datagram.size());
    110 //        QString msg = datagram.data();
    111 //        ui->textEdit->append(msg.left(datagram.size()));
    112 //    }
    113     QByteArray array = tcpsocket->readAll();
    114     ui->textEdit->append(array);
    115 }
    116 
    117 void TcpClient::on_pushButtonSend_clicked()
    118 {
    119     if(ui->lineEditSend->text() == "")
    120     {
    121         return;
    122     }
    123     QString msg = userName + ":" + ui->lineEditSend->text();
    124    // tcpsocket->write((char*)msg.toUtf8().data(), msg.length());
    125     tcpsocket->write(msg.toUtf8().data());
    126     ui->lineEditSend->clear();
    127 }
    128 
    129 void TcpClient::slotdisconnected()
    130 {
    131     ui->pushButtonSend->setEnabled(false);
    132     ui->pushButtonEnter->setText(QStringLiteral("进入聊天室"));
    133 }
    View Code

    TcpClient.ui

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <ui version="4.0">
      3  <class>TcpClient</class>
      4  <widget class="TcpClient" name="TcpClient">
      5   <property name="geometry">
      6    <rect>
      7     <x>0</x>
      8     <y>0</y>
      9     <width>341</width>
     10     <height>463</height>
     11    </rect>
     12   </property>
     13   <property name="windowTitle">
     14    <string>TcpClient</string>
     15   </property>
     16   <widget class="QPushButton" name="pushButtonSend">
     17    <property name="geometry">
     18     <rect>
     19      <x>230</x>
     20      <y>300</y>
     21      <width>75</width>
     22      <height>23</height>
     23     </rect>
     24    </property>
     25    <property name="text">
     26     <string>发送</string>
     27    </property>
     28   </widget>
     29   <widget class="QPushButton" name="pushButtonEnter">
     30    <property name="geometry">
     31     <rect>
     32      <x>40</x>
     33      <y>430</y>
     34      <width>261</width>
     35      <height>23</height>
     36     </rect>
     37    </property>
     38    <property name="text">
     39     <string>加入或离开聊天室</string>
     40    </property>
     41   </widget>
     42   <widget class="QTextEdit" name="textEdit">
     43    <property name="geometry">
     44     <rect>
     45      <x>20</x>
     46      <y>10</y>
     47      <width>271</width>
     48      <height>281</height>
     49     </rect>
     50    </property>
     51   </widget>
     52   <widget class="QLabel" name="label">
     53    <property name="geometry">
     54     <rect>
     55      <x>40</x>
     56      <y>340</y>
     57      <width>54</width>
     58      <height>12</height>
     59     </rect>
     60    </property>
     61    <property name="text">
     62     <string>名字:</string>
     63    </property>
     64   </widget>
     65   <widget class="QLabel" name="label_2">
     66    <property name="geometry">
     67     <rect>
     68      <x>40</x>
     69      <y>370</y>
     70      <width>54</width>
     71      <height>12</height>
     72     </rect>
     73    </property>
     74    <property name="text">
     75     <string>服务地址:</string>
     76    </property>
     77   </widget>
     78   <widget class="QLabel" name="label_3">
     79    <property name="geometry">
     80     <rect>
     81      <x>40</x>
     82      <y>400</y>
     83      <width>54</width>
     84      <height>12</height>
     85     </rect>
     86    </property>
     87    <property name="text">
     88     <string>服务端口:</string>
     89    </property>
     90   </widget>
     91   <widget class="QLineEdit" name="lineEditUserName">
     92    <property name="geometry">
     93     <rect>
     94      <x>100</x>
     95      <y>340</y>
     96      <width>113</width>
     97      <height>20</height>
     98     </rect>
     99    </property>
    100   </widget>
    101   <widget class="QLineEdit" name="lineEditServerIp">
    102    <property name="geometry">
    103     <rect>
    104      <x>100</x>
    105      <y>370</y>
    106      <width>113</width>
    107      <height>20</height>
    108     </rect>
    109    </property>
    110   </widget>
    111   <widget class="QLineEdit" name="lineEditServerPort">
    112    <property name="geometry">
    113     <rect>
    114      <x>100</x>
    115      <y>400</y>
    116      <width>113</width>
    117      <height>20</height>
    118     </rect>
    119    </property>
    120   </widget>
    121   <widget class="QLineEdit" name="lineEditSend">
    122    <property name="geometry">
    123     <rect>
    124      <x>20</x>
    125      <y>300</y>
    126      <width>201</width>
    127      <height>20</height>
    128     </rect>
    129    </property>
    130   </widget>
    131  </widget>
    132  <customwidgets>
    133   <customwidget>
    134    <class>TcpClient</class>
    135    <extends>QWidget</extends>
    136    <header>tcpclient.h</header>
    137    <container>1</container>
    138   </customwidget>
    139  </customwidgets>
    140  <resources/>
    141  <connections/>
    142 </ui>
    View Code
    作者:疯狂Delphi
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

    欢迎关注我,一起进步!扫描下方二维码即可加我

  • 相关阅读:
    POJ 3468_A Simple Problem with Integers(树状数组)
    POJ 3468_A Simple Problem with Integers(线段树)
    ZOJ 2770_Burn the Linked Camp
    ZOJ 2770_Burn the Linked Camp
    POJ 3169_Layout
    POJ 3169_Layout
    POJ 3684_Physics Experiment
    POJ 3255_Roadblocks
    POJ 3723 Conscription【最小生成树】
    POJ 3279 Fliptile【枚举】
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/15045049.html
Copyright © 2011-2022 走看看