1. 程式人生 > >QT之TCP通訊

QT之TCP通訊

QT中可以通過TCP協議讓伺服器和客戶端之間行通訊。所以下面我就圍繞伺服器和客戶端來寫。

這是我們寫伺服器和客戶端的具體流程:

A、伺服器:      

         1.建立QTcpServer物件
         2.啟動伺服器(監聽)呼叫成員方法listen(QHostAddress::Any,埠號)
         3.當有客戶端連結時候會發送newConnection訊號,觸發槽函式接受連結(得到一個與客戶端通訊的套接字QTcpSocket)
         4.QTcpsocket傳送資料用成員方法write,
         5.讀資料當客戶端有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

B、客戶端  :  

        1.建立QTcpSocket物件
        2.連結伺服器connectToHost(QHostAddress("ip"),埠號)
        3.QTcpsocket傳送資料用成員方法write,
        4.讀資料當對方有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

 

我們需要呼叫到的標頭檔案有兩個:

#include <QTcpServer>  
#include <QTcpSocket>

我們先要在工程檔案中加入network

QT       += core gui network

下面我們來看看伺服器程式步驟:

1、初始化伺服器server物件

mServer = new QTcpServer();

2、啟動監聽伺服器

  mServer->listen(QHostAddress::Any,9988);//9988為埠號

3、當有客戶端連結時候會發送newConnection訊號,觸發槽函式接受連結(得到一個與客戶端通訊的套接字QTcpSocket)

 connect(mServer,SIGNAL(newConnection()),this,SLOT(new_client()));
 mSocket = mServer->nextPendingConnection();//與客戶端通訊的套接字

4、傳送資料

 mSocket->write(msg.toUtf8());

5、讀資料當客戶端有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

 connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_client_data()));

6、連線多個客戶端

 //可以實現同時讀取多個客戶端傳送過來的訊息
 QTcpSocket *obj = (QTcpSocket*)sender();

7、檢測掉線

 connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis())); //檢測掉線訊號

下面是伺服器的實現的具體程式碼:

複製程式碼
 1 #include "tcpserver.h"
 2 #include "ui_tcpserver.h"
 3 #include <QDebug>
 4 TcpServer::TcpServer(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::TcpServer)
 7 {
 8     ui->setupUi(this);
 9     //初始化伺服器server物件
10     mServer = new QTcpServer();
11     //關聯客戶端連線訊號newConnection
12     connect(mServer,SIGNAL(newConnection()),this,SLOT(new_client())); //連線客戶端
13     //啟動伺服器監聽
14     mServer->listen(QHostAddress::Any,9988);
15 
16 }
17 
18 TcpServer::~TcpServer()
19 {
20     delete ui;
21 }
22 
23 void TcpServer::new_client()
24 {
25     qDebug()<<"新客戶段連線";
26     mSocket = mServer->nextPendingConnection();//與客戶端通訊的套接字
27     //關聯接收客戶端資料訊號readyRead訊號(客戶端有資料就會發readyRead訊號)
28     connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_client_data()));
29     //檢測掉線訊號
30     connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));
31 
32 }
33 
34 void TcpServer::read_client_data()
35 {
36     //可以實現同時讀取多個客戶端傳送過來的訊息
37     QTcpSocket *obj = (QTcpSocket*)sender();
38     QString msg = obj->readAll();
39     qDebug()<<msg;
40 }
41 
42 void TcpServer::client_dis()
43 {
44      QTcpSocket *obj = (QTcpSocket*)sender();//掉線物件
45      qDebug()<<obj->peerAddress().toString();//打印出掉線物件的ip
46 }
複製程式碼

 

說完伺服器那我們繼續來看看客戶端是怎麼實現的:

1、建立QTcpSocket物件

 mSocket = new QTcpSocket();

2、連結伺服器connectToHost(QHostAddress("ip"),埠號),連線伺服器ip和埠號

 mSocket->connectToHost(ui->ipEdit->text(),ui->portEdit->text().toInt()); //ui->ipEdit->text():ip,ui->portEdit->text().toInt():埠號

3、傳送資料

//取傳送資訊編輯框內容
QString msg = ui->sendEdit->toPlainText();
mSocket->write(msg.toUtf8());//轉編碼

4、檢測連結成功訊號關聯槽函式

 connect(mSocket,SIGNAL(connected()),this,SLOT(connect_suc()));

5、檢測掉線訊號

 connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));

6、伺服器和客戶端關閉都可以使用close

 mSocket->close();

這是客戶端實現的具體程式碼

複製程式碼
 1 #include "tcpclient.h"
 2 #include "ui_tcpclient.h"
 3 #include <QDebug>
 4 TcpClient::TcpClient(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::TcpClient)
 7 {
 8     ui->setupUi(this);
 9     //初始化套接字物件
10     mSocket = new QTcpSocket();
11     //關聯資料訊號
12     connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
13 
14 }
15 
16 TcpClient::~TcpClient()
17 {
18     delete ui;
19 }
20 
21 void TcpClient::read_data()
22 {
23     QString msg = mSocket->readAll();
24     qDebug()<<msg;
25 }
26 
27 void TcpClient::on_btn_connectServer_clicked()
28 {
29     //檢測連結成功訊號關聯槽函式
30     connect(mSocket,SIGNAL(connected()),this,SLOT(connect_suc()));
31     //檢測掉線訊號
32     connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));
33     //連線伺服器,設定ip和埠號
34     mSocket->connectToHost(ui->ipEdit->text(),ui->portEdit->text().toInt());
35 
36 }
37 
38 void TcpClient::on_btn_send_clicked()
39 {
40     //取傳送資訊編輯框內容
41     QString msg = ui->sendEdit->toPlainText();
42     mSocket->write(msg.toUtf8());//轉編碼
43 }
44 
45 void TcpClient::connect_suc()
46 {
47     ui->btn_connectServer->setEnabled(false);//如果連線成功則連線按鈕不能按下
48 }
49 void TcpClient::client_dis()
50 {
51     ui->btn_connectServer->setEnabled(true);//如果連線沒有成功則連線按鈕還可以按下
52 }
複製程式碼

 

這是伺服器和客戶端分開兩個資料夾寫的程式,在這裡我也實現了伺服器和客戶端寫在同一個檔案中

具體程式碼如下:

標頭檔案:tcpapp.h

  View Code

原始檔:tcpapp.cpp

  View Code

介面檔案tcpapp.ui如下圖

 

此外這裡還使用到了容器,在這裡講講容器的使用

1、定義容器物件

QVector<QTcpSocket*> clients; //儲存所有線上客戶端(容器)
  解釋:QTcpSocke*  容器的型別
       clients  容器名

2、往容器中新增成員

//上線使用者新增到客戶列表容器
 clients.append(mSocket); 

3、尋找某個成員在容器中位置

 int row = clients.indexOf(obj);//找到掉線物件的內容所在的行

4、從容器中刪除成員

  clients.remove(row);//從容器中刪除成員

 

鑑於本人才疏學淺,所以其中不免有遺漏或者錯誤,懇請各位博友批評指正。

QT中可以通過TCP協議讓伺服器和客戶端之間行通訊。所以下面我就圍繞伺服器和客戶端來寫。

這是我們寫伺服器和客戶端的具體流程:

A、伺服器:      

         1.建立QTcpServer物件
         2.啟動伺服器(監聽)呼叫成員方法listen(QHostAddress::Any,埠號)
         3.當有客戶端連結時候會發送newConnection訊號,觸發槽函式接受連結(得到一個與客戶端通訊的套接字QTcpSocket)
         4.QTcpsocket傳送資料用成員方法write,
         5.讀資料當客戶端有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

B、客戶端  :  

        1.建立QTcpSocket物件
        2.連結伺服器connectToHost(QHostAddress("ip"),埠號)
        3.QTcpsocket傳送資料用成員方法write,
        4.讀資料當對方有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

 

我們需要呼叫到的標頭檔案有兩個:

#include <QTcpServer>  
#include <QTcpSocket>

我們先要在工程檔案中加入network

QT       += core gui network

下面我們來看看伺服器程式步驟:

1、初始化伺服器server物件

mServer = new QTcpServer();

2、啟動監聽伺服器

  mServer->listen(QHostAddress::Any,9988);//9988為埠號

3、當有客戶端連結時候會發送newConnection訊號,觸發槽函式接受連結(得到一個與客戶端通訊的套接字QTcpSocket)

 connect(mServer,SIGNAL(newConnection()),this,SLOT(new_client()));
 mSocket = mServer->nextPendingConnection();//與客戶端通訊的套接字

4、傳送資料

 mSocket->write(msg.toUtf8());

5、讀資料當客戶端有資料來,QTcpSocket物件就會發送readyRead訊號,關聯槽函式讀取資料

 connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_client_data()));

6、連線多個客戶端

 //可以實現同時讀取多個客戶端傳送過來的訊息
 QTcpSocket *obj = (QTcpSocket*)sender();

7、檢測掉線

 connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis())); //檢測掉線訊號

下面是伺服器的實現的具體程式碼:

複製程式碼
 1 #include "tcpserver.h"
 2 #include "ui_tcpserver.h"
 3 #include <QDebug>
 4 TcpServer::TcpServer(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::TcpServer)
 7 {
 8     ui->setupUi(this);
 9     //初始化伺服器server物件
10     mServer = new QTcpServer();
11     //關聯客戶端連線訊號newConnection
12     connect(mServer,SIGNAL(newConnection()),this,SLOT(new_client())); //連線客戶端
13     //啟動伺服器監聽
14     mServer->listen(QHostAddress::Any,9988);
15 
16 }
17 
18 TcpServer::~TcpServer()
19 {
20     delete ui;
21 }
22 
23 void TcpServer::new_client()
24 {
25     qDebug()<<"新客戶段連線";
26     mSocket = mServer->nextPendingConnection();//與客戶端通訊的套接字
27     //關聯接收客戶端資料訊號readyRead訊號(客戶端有資料就會發readyRead訊號)
28     connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_client_data()));
29     //檢測掉線訊號
30     connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));
31 
32 }
33 
34 void TcpServer::read_client_data()
35 {
36     //可以實現同時讀取多個客戶端傳送過來的訊息
37     QTcpSocket *obj = (QTcpSocket*)sender();
38     QString msg = obj->readAll();
39     qDebug()<<msg;
40 }
41 
42 void TcpServer::client_dis()
43 {
44      QTcpSocket *obj = (QTcpSocket*)sender();//掉線物件
45      qDebug()<<obj->peerAddress().toString();//打印出掉線物件的ip
46 }
複製程式碼

 

說完伺服器那我們繼續來看看客戶端是怎麼實現的:

1、建立QTcpSocket物件

 mSocket = new QTcpSocket();

2、連結伺服器connectToHost(QHostAddress("ip"),埠號),連線伺服器ip和埠號

 mSocket->connectToHost(ui->ipEdit->text(),ui->portEdit->text().toInt()); //ui->ipEdit->text():ip,ui->portEdit->text().toInt():埠號

3、傳送資料

//取傳送資訊編輯框內容
QString msg = ui->sendEdit->toPlainText();
mSocket->write(msg.toUtf8());//轉編碼

4、檢測連結成功訊號關聯槽函式

 connect(mSocket,SIGNAL(connected()),this,SLOT(connect_suc()));

5、檢測掉線訊號

 connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));

6、伺服器和客戶端關閉都可以使用close

 mSocket->close();

這是客戶端實現的具體程式碼

複製程式碼
 1 #include "tcpclient.h"
 2 #include "ui_tcpclient.h"
 3 #include <QDebug>
 4 TcpClient::TcpClient(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::TcpClient)
 7 {
 8     ui->setupUi(this);
 9     //初始化套接字物件
10     mSocket = new QTcpSocket();
11     //關聯資料訊號
12     connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
13 
14 }
15 
16 TcpClient::~TcpClient()
17 {
18     delete ui;
19 }
20 
21 void TcpClient::read_data()
22 {
23     QString msg = mSocket->readAll();
24     qDebug()<<msg;
25 }
26 
27 void TcpClient::on_btn_connectServer_clicked()
28 {
29     //檢測連結成功訊號關聯槽函式
30     connect(mSocket,SIGNAL(connected()),this,SLOT(connect_suc()));
31     //檢測掉線訊號
32     connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_dis()));
33     //連線伺服器,設定ip和埠號
34     mSocket->connectToHost(ui->ipEdit->text(),ui->portEdit->text().toInt());
35 
36 }
37 
38 void TcpClient::on_btn_send_clicked()
39 {
40     //取傳送資訊編輯框內容
41     QString msg = ui->sendEdit->toPlainText();
42     mSocket->write(msg.toUtf8());//轉編碼
43 }
44 
45 void TcpClient::connect_suc()
46 {
47     ui->btn_connectServer->setEnabled(false);//如果連線成功則連線按鈕不能按下
48 }
49 void TcpClient::client_dis()
50 {
51     ui->btn_connectServer->setEnabled(true);//如果連線沒有成功則連線按鈕還可以按下
52 }
複製程式碼

 

這是伺服器和客戶端分開兩個資料夾寫的程式,在這裡我也實現了伺服器和客戶端寫在同一個檔案中

具體程式碼如下:

標頭檔案:tcpapp.h

  View Code

原始檔:tcpapp.cpp

  View Code

介面檔案tcpapp.ui如下圖

 

此外這裡還使用到了容器,在這裡講講容器的使用

1、定義容器物件

QVector<QTcpSocket*> clients; //儲存所有線上客戶端(容器)
  解釋:QTcpSocke*  容器的型別
       clients  容器名

2、往容器中新增成員

//上線使用者新增到客戶列表容器
 clients.append(mSocket); 

3、尋找某個成員在容器中位置

 int row = clients.indexOf(obj);//找到掉線物件的內容所在的行

4、從容器中刪除成員

  clients.remove(row);//從容器中刪除成員