【Qt专栏】Qt实现TCP服务端和客户端通信


前言

网络通信是程序员必须会的一项生存技能,这里简单的实现了服务端和客户端通信的两个小示例,代码可以直接拿来用,开发环境是Qt5.9.6。


一、TCP服务端

1.项目架构

转载求注明来源

2.tcpserver.h文件
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QWidget>
//添加下面三个头文件,记得在pro文件里添加 network 模块
#include <QTcpServer>
#include <QTcpSocket>
#include <QtNetwork>

namespace Ui {
class TCPServer;
}

class TCPServer : public QWidget
{
    Q_OBJECT

public:
    explicit TCPServer(QWidget *parent = nullptr);
    ~TCPServer();
    void initNetwork(QString ip,quint16 port);
    void stopNetwork();

private slots:
    void    onNewConnection();//QTcpServer的newConnection()信号
    void    onConnected();	//可以不添加该接口
    void    onDisconnected();	//可以不添加该接口
    void    onSocketReadyRead();//读取socket传入的数据

    void on_pushButton_clicked();

private:
    Ui::TCPServer *ui;

    QTcpServer *tcpServer; //TCP服务器
    QTcpSocket *tcpSocket;//TCP通讯的Socket

    QString getLocalIP();//获取本机IP地址
    void    closeEvent(QCloseEvent *event);
};

#endif // TCPSERVER_H
3.tcpserver.cpp文件
#include "tcpserver.h"
#include "ui_tcpserver.h"

TCPServer::TCPServer(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TCPServer)
{
    ui->setupUi(this);
    initNetwork(getLocalIP(),55555);    //指定ip地址和监听的端口号
}

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

void TCPServer::initNetwork(QString ip, quint16 port)
{
    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));

    QHostAddress addr(ip);
    tcpServer->listen(addr,port);
}

void TCPServer::stopNetwork()
{
    if(tcpServer->isListening()){//tcpServer正在监听
        tcpServer->close();;//停止网络监听
    }
}

void TCPServer::onNewConnection()
{
    tcpSocket = tcpServer->nextPendingConnection(); //创建socket
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
    connect(tcpSocket, SIGNAL(connected()),this, SLOT(onConnected()));
    onConnected();
    connect(tcpSocket, SIGNAL(disconnected()),this, SLOT(onDisconnected()));
}

void TCPServer::onConnected()
{
    ui->plainTextEdit->appendPlainText(QStringLiteral("***客户端连接 ")
                                       +QStringLiteral("ip地址:")+tcpSocket->peerAddress().toString()
                                       +QStringLiteral(" 端口号:")+QString::number(tcpSocket->peerPort())+"***");
}

void TCPServer::onDisconnected()
{
    ui->plainTextEdit->appendPlainText(QStringLiteral("***客户端断开连接***"));
}


void TCPServer::onSocketReadyRead()
{
    while(tcpSocket->canReadLine()){
        QByteArray msg = tcpSocket->readLine();
        ui->plainTextEdit->appendPlainText("[客户端] "+msg);
    }
}

QString TCPServer::getLocalIP()
{
    QString ipString = Q_NULLPTR;
    QHostInfo hostInfo = QHostInfo::fromName(QHostInfo::localHostName());   //从本地主机名称获取主机信息
    QList<QHostAddress> listAddr = hostInfo.addresses();    //本地主机ip地址列表(IPV4/IPV6)
    foreach (auto addr, listAddr)
    {
       if((addr.isNull() == false) && (addr.protocol() == QAbstractSocket::IPv4Protocol)
               && (addr != QHostAddress::LocalHost))
       {
           ipString = addr.toString();   //根据条件筛选出本地IPV4地址
       }
    }
    return ipString;
}

void TCPServer::closeEvent(QCloseEvent *event)
{
    stopNetwork();
    event->accept();
}

void TCPServer::on_pushButton_clicked()
{
    QString msg = ui->lineEdit->text();
    ui->lineEdit->setFocus();//光标回到lineEdit
    if(msg.isEmpty())return;
    ui->lineEdit->clear();
    ui->plainTextEdit->appendPlainText("[服务端] "+msg);

    QByteArray str = msg.toUtf8();
    str.append("\n");
    tcpSocket->write(str);
}
4.测试效果

在这里插入图片描述

二、TCP客户端

1.项目架构

在这里插入图片描述

2.tcpserver.h文件
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QWidget>
//添加下面两个头文件,记得在pro文件里添加 network 模块
#include    <QTcpSocket>
#include    <QtNetwork>

namespace Ui {
class TCPClient;
}

class TCPClient : public QWidget
{
    Q_OBJECT

public:
    explicit TCPClient(QWidget *parent = nullptr);
    ~TCPClient();
    void initNetwork(QString ip,quint16 port);
    void stopNetwork();

private slots:
//自定义槽函数
    void    onConnected();	//可以不添加该接口
    void    onDisconnected();	//可以不添加该接口
    void    onSocketReadyRead();//读取socket传入的数据

    void on_pushButton_clicked();

private:
    Ui::TCPClient *ui;
    QTcpSocket  *tcpClient;  //socket
    QString getLocalIP();//获取本机IP地址
    void    closeEvent(QCloseEvent *event);
};

#endif // TCPCLIENT_H
3.tcpserver.cpp文件
#include "tcpclient.h"
#include "ui_tcpclient.h"

TCPClient::TCPClient(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TCPClient)
{
    ui->setupUi(this);
    initNetwork(getLocalIP(),55555);    //指定服务端ip地址和的端口号
}

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

void TCPClient::initNetwork(QString ip, quint16 port)
{
    tcpClient=new QTcpSocket(this); //创建socket变量

    connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));

    tcpClient->connectToHost(ip,port);
}

void TCPClient::stopNetwork()
{
    //断开与服务器的连接
    if (tcpClient->state()==QAbstractSocket::ConnectedState){
        tcpClient->disconnectFromHost();
    }
}

void TCPClient::onConnected()
{
    ui->plainTextEdit->appendPlainText("***已连接到服务器***");
}

void TCPClient::onDisconnected()
{
    ui->plainTextEdit->appendPlainText("***已断开与服务器的连接***");
}

void TCPClient::onSocketReadyRead()
{
    while(tcpClient->canReadLine()){
        QByteArray msg = tcpClient->readLine();
        ui->plainTextEdit->appendPlainText("[服务端] "+msg);
    }
}

QString TCPClient::getLocalIP()
{
    QString ipString = Q_NULLPTR;
    QHostInfo hostInfo = QHostInfo::fromName(QHostInfo::localHostName());   //从本地主机名称获取主机信息
    QList<QHostAddress> listAddr = hostInfo.addresses();    //本地主机ip地址列表(IPV4/IPV6)
    foreach (auto addr, listAddr)
    {
       if((addr.isNull() == false) && (addr.protocol() == QAbstractSocket::IPv4Protocol)
               && (addr != QHostAddress::LocalHost))
       {
           ipString = addr.toString();   //根据条件筛选出本地IPV4地址
       }
    }
    return ipString;
}

void TCPClient::closeEvent(QCloseEvent *event)
{
    stopNetwork();
    event->accept();
}

void TCPClient::on_pushButton_clicked()
{
    //发送数据
    QString  msg=ui->lineEdit->text();
    ui->lineEdit->setFocus();//光标回到lineEdit
    if(msg.isEmpty())return;
    ui->lineEdit->clear();
    ui->plainTextEdit->appendPlainText("[客户端] "+msg);

    QByteArray  str=msg.toUtf8();
    str.append('\n');
    tcpClient->write(str);
}
4.测试效果

在这里插入图片描述


总结

好了,两个小程序写完并可以运行进行通信,简单的实现,原理后序会专门写篇文章,这里可以直接照着上述写就OK啦,886!

  • 8
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Qt是一个跨平台的C++应用程序框架,它提供了丰富的库和工具来帮助开发者创建各种类型的应用程序,包括网络通信应用。 在Qt实现TCP服务端客户端通信非常简单。首先,我们需要创建一个QTcpServer对象来作为服务端,该对象负责监听客户端的连接请求。接下来,我们需要为QTcpServer对象绑定一个IP地址和端口号,以便客户端能够连接到该地址和端口。当有新的客户端连接时,QTcpServer对象会发出newConnection()信号。 在服务端的槽函数中,我们可以使用QTcpServer的nextPendingConnection()函数获取新连接的QTcpSocket对象,该对象用于和客户端进行通信。我们可以在该对象上发送和接收数据,以实现服务端客户端之间的数据交互。 接下来,我们需要创建一个QTcpSocket对象作为客户端,该对象负责和服务端建立连接。我们需要使用connectToHost()函数来指定要连接的服务端IP地址和端口号。一旦连接成功,QTcpSocket对象会发出connected()信号。 在客户端的槽函数中,我们可以使用QTcpSocket对象发送和接收数据。我们可以使用write()函数发送数据,使用readyRead()信号和read()函数接收数据。 通过这种方式,我们可以在服务端客户端之间进行双向的数据通信服务端可以同时接受多个客户端的连接,每个客户端都可以和服务端进行独立的数据交互。 总的来说,使用Qt实现TCP服务端客户端通信非常方便。通过使用QTcpServer和QTcpSocket类,我们可以轻松地建立连接,发送和接收数据。这种通信方式可以应用于多种场景,如实时聊天、远程控制等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉伊卜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值