亲宝软件园·资讯

展开

Qt TCP通信功能

xundao_803817 人气:0

在.pro文件中添加网络模块 Qt += network

服务端:

1. 创建QTcpServer 对象,用于监听,创建套接字等;

QTcpServer * serverSocket = new QTcpServer(this);

2.进行监听,通过QTcpServer对象 QTcpServer::listen();

bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);

例子:

// 获取单行输入框输入的数为端口号
short port = ui->lineEdit->text().toInt();
tcpServer->listen(QHostAddress::Any, port); // QHostAddress::Any表示自动绑定

3.使用信号槽,connect(), 判断是否有客户端来连接,QTcpServer::newConnection();

[signal] void QTcpServer::newConnection()

例子:

// 3.基于 QTcpServer::newConnection() 信号检测是否有新客户端连接
connect(tcpServer, &QTcpServer::newConnection, this, [=]()
    {
        // 创建用于通信的套接字
        // 4.如果有新的客户端连接调用 QTcpSocket* QTcpServer::nextPendingConnection()
        // 在通信编辑框中显示成功与客户端取得连接
        // 5.准备与客户端通信
        // 6.判断客户端是否断开连接    
    });

4.在步骤3的基础上,创建套接字,QTcpSocket socketServer = QTcpServer::nextPendingConnection();

5.在步骤3的基础上,使用信号槽connect(),判断是否接收客户端发了 的信息QTcpSocket::readyRead();

6. 在步骤5的基础上,通过套接字调用readAll() ,读取客户端发来的信息;

7.在步骤3的基础上,通过套接字判断客户端是否下线,关闭套接字;

客户端:

1. 创建套接字对象,用于通信 QTcpSocket *clientSocket = new QTcpSocket(this);

2. 调用信号槽,connect() ,判断是否成功连接服务端connected;

3. 调用信号槽,connect() , 判断是否接受来着服务端发来的信息 readyRead();

4. 在步骤3的基础上,利用套接字对象调用readAll() 方法,读取服务端发来的消息;

5. 利用套接字调用write() 方法,将消息发送给服务端;

6. 调用信号槽,connect() , 判断是否断开连接,释放套接字;

服务端代码:

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
 
#include "QDebug"
#include <QMessageBox>
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    // 设置窗口名称
    setWindowTitle(QString("Server-TCP"));
    setWindowIcon(QIcon(QPixmap("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png")));
 
    // 刚进来是将连接状态图片置成灰色的
    m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png"));
 
    // 2.socket 通信
    //tcpSocket = new QTcpSocket();
    // 获取套接字
    // 服务端通信流程
    // 1.创建套接字服务器 QTcpServer对象
    tcpServer = new QTcpServer(this);
    // 2.通过QTcpServer对象设置监听,即QTcpServer::listen()
    // 3.基于 QTcpServer::newConnection() 信号检测是否有新客户端连接
    connect(tcpServer, &QTcpServer::newConnection, this, [=]()
    {
        // 成功连接则切换图片颜色
        m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本.png"));
 
        // 创建用于通信的套接字
        // 4.如果有新的客户端连接调用 QTcpSocket* QTcpServer::nextPendingConnection()
        tcpSocket = tcpServer->nextPendingConnection();
        // 在通信编辑框中显示成功与客户端取得连接
        ui->textEdit->append("成功与客户端取得连接!!!");
        // 5.准备与客户端通信
        connect(tcpSocket, &QTcpSocket::readyRead, this, [=]()
        {
            // 调用套接字读取客户端发的数据
            QString acceptText = tcpSocket->readAll(); // QByteArray 可以强制转成 QString
            // 将读取到的数据写到通信编辑框中
            ui->textEdit->append("客户端say:" + acceptText);
        });
 
        // 6.判断客户端是否断开连接
        connect(tcpSocket, &QTcpSocket::disconnected, this, [=]()
        {
            //QMessageBox(, QMessageBox::Warning, );
            QMessageBox::warning(this, "连接状态", "客户端已断开连接");
            tcpSocket->deleteLater();
            // 将连接状态图片置成灰色的
            m_pixmap.load(QString("D:\\BaiduNetdiskDownload\\Res WWW\\picture\\ico\\01_副本_副本.png"));
 
            //tcpServer->deleteLater();
        });
 
    });
 
    // 1.状态栏显示信息
    showMessageStatusBar();
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
// 状态栏添加提示信息
void MainWindow::showMessageStatusBar()
{
    // 设置窗口名称
    //QWidget::windowTitleChanged("Server-TCP");
    //ui->statusBar->setWindowTitle();
 
    // 通过加载QLable给状态栏显示文本
    QLabel *pLable = new QLabel();
    QLabel *lableText = new QLabel(QString::fromUtf8("连接状态:"));
 
    //lableText->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    //pLable->setMinimumWidth(this->width()/2);
 
    //= new QLabel(QString::fromUtf8("连接状态:"));
    // 设置lable标签的大小
    //pLable->setMinimumSize(pLable->sizeHint());
    pLable->setFixedSize(30, 30);
 
    m_pixmap.scaled(pLable->width(), pLable->height());
    // 显示图片
    pLable->setPixmap(m_pixmap);
    // 按比例缩小图片
 
    //pLable->setFixedSize(QSize(50,50));
    // 设置状态栏样式
    //ui->statusBar->setStyleSheet(QString("QString::item{border:0px"));  // 不显示边框
    // 将标签加入到状态栏中
    ui->statusBar->addWidget(lableText);
    ui->statusBar->addPermanentWidget(pLable);//
}
 
// 处理点击启动服务器,进行监听
void MainWindow::on_pushButton_clicked()
{
    //qDebug() << "点击了 启动服务器按钮\n";
    // 获取输入框输入的数为端口号
    short port = ui->lineEdit->text().toInt();
    tcpServer->listen(QHostAddress::Any, port);
}
 
// 将数据发生给客户端
void MainWindow::on_pushButton_2_clicked()
{
    // 将发送数据编辑栏的文本通过套接字发生给客户端
    tcpSocket->write(ui->textEdit_2->toPlainText().toUtf8());
    // 需要将要发生的数据写到通信编辑栏中
    ui->textEdit->append("服务端say:" + ui->textEdit_2->toPlainText().toUtf8());
    // 清空发送消息编辑框
    ui->textEdit_2->clear();
}

mainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
 
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
    // 在状态栏中设置文本+图标
    void showMessageStatusBar();
 
    QTcpServer* tcpServer;
    QTcpSocket* tcpSocket;
 
private slots:
    void on_pushButton_clicked();
 
    void on_pushButton_2_clicked();
 
private:
    Ui::MainWindow *ui;
    // 用于加载图片路径
    QPixmap m_pixmap;
};
 
#endif // MAINWINDOW_H

程序UI

客户端:

client.cpp

#include "client.h"
#include "ui_client.h"
 
Client::Client(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Client)
{
    ui->setupUi(this);
 
    // 通信流程
    //1、创建套接字对象
    clientSocket = new QTcpSocket(this);
    //2、调用QTcpSocket::connectToHost() 绑定服务端IP和端口
 
    //3、通过套接字与服务端进行通信 收发
    // 判断是否成功连接服务端 开始读取服务端发来的信息
    connect(clientSocket, &QTcpSocket::readyRead, this, [=]()
    {
        // 通过套接字读取发来的信息
        QByteArray receiveAll = clientSocket->readAll();
        // 将获取到的信息显示到通信编辑栏中
        ui->textEdit_Record->append("服务端say:" + receiveAll);
    });
 
    // 开始的时候断开连接按钮置成不可用状态
    ui->disConBtn->setEnabled(false);
 
    // 判断是否连接成功
    connect(clientSocket, &QTcpSocket::connected, this, [=]()
    {
        // 将成功连接显示到通信记录编辑栏中
        ui->textEdit_Record->append("成功与服务端取得连接!!!");
        // 将断开连接置成可用状态
        ui->disConBtn->setEnabled(true);
    });
 
    // 判断是否断开连接
    connect(clientSocket, &QTcpSocket::disconnected, this, [=]()
    {
        // 将服务端断开连接显示到通信编辑框中
        ui->textEdit_Record->append("注意服务端已断开连接!!!");
        // 将连接服务端按钮置成不可用状态
        ui->conBtn->setEnabled(false);
    });
 
}
 
Client::~Client()
{
    delete ui;
}
 
// 点击按钮连接服务器,绑定地址与端口
void Client::on_conBtn_clicked()
{
    // 获取编辑框中的ip和端口
    unsigned short port = ui->lineEdit_port->text().toUShort();
    QString addr = ui->lineEdit_add->text();
    clientSocket->connectToHost(addr, port);
    // 需要将按钮置成不可用状态
    ui->conBtn->setEnabled(false);
}
 
// 断开连接
void Client::on_disConBtn_clicked()
{
    //clientSocket->disconnected();
    // 关闭套接字
    clientSocket->close();
    // 将客户端断开连接提示显示到通信编辑框中
    ui->textEdit_Record->append("注意客户端已断开连接!!!");
    // 将连接服务端按钮置成可用状态
    ui->conBtn->setEnabled(true);
}
 
// 点击按钮发送数据
void Client::on_sendBtn_clicked()
{
    // 获取发送信息编辑框的文本
    //ui->textEdit_Send->toPlainText().toUtf8();
 
    // 将获取到的信息发送给服务端
    clientSocket->write(ui->textEdit_Send->toPlainText().toUtf8());
    // 将发送的信息显示到通信记录编辑框中
    ui->textEdit_Record->append(ui->textEdit_Send->toPlainText().toUtf8());
    // 需要将发送编辑框清空缓存
    ui->textEdit_Send->clear();
}

client.h

#ifndef CLIENT_H
#define CLIENT_H
 
#include <QMainWindow>
#include <QTcpSocket>
 
namespace Ui {
class Client;
}
 
class Client : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit Client(QWidget *parent = nullptr);
    ~Client();
 
private slots:
    void on_conBtn_clicked();
 
    void on_disConBtn_clicked();
 
    void on_sendBtn_clicked();
 
private:
    Ui::Client *ui;
 
    // 创建套接字
    QTcpSocket * clientSocket;
};
 
#endif // CLIENT_H

程序UI

加载全部内容

相关教程
猜你喜欢
用户评论