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