欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt中的TCP服务端和客户端互发消息

程序员文章站 2022-05-21 13:44:00
...

Qt中的TCP服务端和客户端互发消息

Qt中的TCP服务端和客户端互发消息

作者:hackett
微信公众号:加班猿

废话不多说,上演示效果
Qt中的TCP服务端和客户端互发消息

由于我们用到socketLamda表达式,所以工程.pro文件需要添加对应的库

Qt中的TCP服务端和客户端互发消息

为了方便,main.cpp中让程序显示两个Widget窗口,程序运行起来就可以测试

ServerWidget w;
w.show();
ClientWidget w2;
w2.show();

一、服务端

服务端的UI界面布局:

2个PushButton(send,close)

2个textEdit(发送内容,接收内容)

Qt中的TCP服务端和客户端互发消息

新建一个监听套接字,监听端口号为9999的IP,等待连接,有连接过来提示成功连接同时服务端读就绪

 //监听套接字,指定父对象,让其自动回收空间
tcpServer = new QTcpServer(this);

tcpServer->listen(QHostAddress::Any, 9999);

setWindowTitle("服务器: 9999");

//newConnection代表有新的连接
connect(tcpServer, &QTcpServer::newConnection,
        [=]()
        {
            //取出建立好连接的套接字
            tcpSocket = tcpServer->nextPendingConnection();

            //获取对方的IP和端口
            QString ip = tcpSocket->peerAddress().toString();
            quint16 port = tcpSocket->peerPort();
            QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
            ui->textEditRead->setText(temp);

            //readyRead代表读就绪
            connect(tcpSocket, &QTcpSocket::readyRead,
                    [=]()
                    {
                        //从通信套接字中取出内容
                        QByteArray array = tcpSocket->readAll();
                        ui->textEditRead->append(array);
                    }
                   );
        }
       );

二、客户端

客户端的UI界面布局:

3个PushButton(connect,send,close)

2个lineEdit(端口号,IP)

2个textEdit(发送内容,接收内容)

Qt中的TCP服务端和客户端互发消息

客户端连接按钮主动与服务端建立连接

void ClientWidget::on_buttonConnect_clicked()
{
    //获取服务器ip和端口
    QString ip = ui->lineEditIP->text();
    qint16 port = ui->lineEditPort->text().toInt();

    //主动和服务器建立连接
    tcpSocket->connectToHost(QHostAddress(ip), port);

}

连接成功后会触发connected,提示"成功和服务器建立好连接"同时客户端读就绪

//分配空间,指定父对象
tcpSocket = new QTcpSocket(this);

setWindowTitle("客户端");


connect(tcpSocket, &QTcpSocket::connected,
        [=]()
        {
            ui->textEditRead->setText("成功和服务器建立好连接");
        }
       );

connect(tcpSocket, &QTcpSocket::readyRead,
        [=]()
        {
            //获取对方发送的内容
            QByteArray array = tcpSocket->readAll();
            //追加到编辑区中
            ui->textEditRead->append(array);
        }

       );

源码

main.cpp

#include "serverwidget.h"
#include <QApplication>
#include "clientwidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ServerWidget w;
    w.show();

    ClientWidget w2;
    w2.show();

    return a.exec();
}

serverwidget.cpp

#include "serverwidget.h"
#include "ui_serverwidget.h"
#include <QDebug>

ServerWidget::ServerWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServerWidget)
{
    ui->setupUi(this);

    tcpServer = NULL;
    tcpSocket = NULL;

    //监听套接字,指定父对象,让其自动回收空间
    tcpServer = new QTcpServer(this);

    tcpServer->listen(QHostAddress::Any, 9999);

    setWindowTitle("服务器: 9999");

    //newConnection代表有新的连接
    connect(tcpServer, &QTcpServer::newConnection,
            [=]()
            {
                //取出建立好连接的套接字
                tcpSocket = tcpServer->nextPendingConnection();

                //获取对方的IP和端口
                QString ip = tcpSocket->peerAddress().toString();
                quint16 port = tcpSocket->peerPort();
                QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
                ui->textEditRead->setText(temp);

                //readyRead代表读就绪
                connect(tcpSocket, &QTcpSocket::readyRead,
                        [=]()
                        {
                            //从通信套接字中取出内容
                            QByteArray array = tcpSocket->readAll();
                            ui->textEditRead->append(array);
                        }
                        );
            }
            );

}

ServerWidget::~ServerWidget()
{
    delete ui;
}

void ServerWidget::on_buttonSend_clicked()
{
    if(NULL == tcpSocket)
    {
        return;
    }
    //获取编辑区内容
    QString str = ui->textEditWrite->toPlainText();
    //给对方发送数据, 使用套接字是tcpSocket
    tcpSocket->write( str.toUtf8().data() );

}

void ServerWidget::on_buttonClose_clicked()
{
    if(NULL == tcpSocket)
    {
        return;
    }

    //主动和客户端端口连接
    tcpSocket->disconnectFromHost();
    tcpSocket->close();
    tcpSocket = NULL;
}

serverwidget.h

#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H

#include <QWidget>
#include <QTcpServer> //监听套接字
#include <QTcpSocket> //通信套接字

namespace Ui {
class ServerWidget;
}

class ServerWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ServerWidget(QWidget *parent = 0);
    ~ServerWidget();

private slots:
    void on_buttonSend_clicked();

    void on_buttonClose_clicked();

private:
    Ui::ServerWidget *ui;

    QTcpServer *tcpServer; //监听套接字
    QTcpSocket *tcpSocket; //通信套接字

};

#endif // SERVERWIDGET_H

clientwidget.cpp

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>

ClientWidget::ClientWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ClientWidget)
{
    ui->setupUi(this);

    tcpSocket = NULL;

    //分配空间,指定父对象
    tcpSocket = new QTcpSocket(this);

    setWindowTitle("客户端");


    connect(tcpSocket, &QTcpSocket::connected,
            [=]()
            {
                ui->textEditRead->setText("成功和服务器建立好连接");
            }
            );

    connect(tcpSocket, &QTcpSocket::readyRead,
            [=]()
            {
                //获取对方发送的内容
                QByteArray array = tcpSocket->readAll();
                //追加到编辑区中
                ui->textEditRead->append(array);
            }

            );

}

ClientWidget::~ClientWidget()
{
    delete ui;
}

void ClientWidget::on_buttonConnect_clicked()
{
    //获取服务器ip和端口
    QString ip = ui->lineEditIP->text();
    qint16 port = ui->lineEditPort->text().toInt();

    //主动和服务器建立连接
    tcpSocket->connectToHost(QHostAddress(ip), port);

}

void ClientWidget::on_buttonSend_clicked()
{
    //获取编辑框内容
    QString str = ui->textEditWrite->toPlainText();
    //发送数据
    tcpSocket->write( str.toUtf8().data() );

}

void ClientWidget::on_buttonClose_clicked()
{
    //主动和对方断开连接
    tcpSocket->disconnectFromHost();
    tcpSocket->close();
}

clientwidget.h

#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H

#include <QWidget>
#include <QTcpSocket> //通信套接字

namespace Ui {
class ClientWidget;
}

class ClientWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ClientWidget(QWidget *parent = 0);
    ~ClientWidget();

private slots:
    void on_buttonConnect_clicked();

    void on_buttonSend_clicked();

    void on_buttonClose_clicked();

private:
    Ui::ClientWidget *ui;

    QTcpSocket *tcpSocket; //通信套接字
};

#endif // CLIENTWIDGET_H

如果你觉得文章还不错,记得"点赞关注"

关注我的微信公众号【 加班猿 】可以获取更多内容

Qt中的TCP服务端和客户端互发消息

相关标签: Qt qt qtcreator