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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM