QT 网络编程 8

本文详细介绍了使用Qt库在C++中实现UDP和TCP通信的基本框架,包括客户端和服务器的代码示例,展示了如何通过QUdpSocket和QTcpSocket进行数据发送和接收的操作。
摘要由CSDN通过智能技术生成

1 基础知识

udp 

 

tcp 

2 UDP

框架

客户端:
QUdpSocket x;
qint64 writeDatagram(
const char *data,
qint64 size, 
const QHostAddress &address, 
quint16 port
);

服务器:
void Server::initSocket(){
      udpSocket = new QUdpSocket(this);
      udpSocket->bind(QHostAddress::LocalHost, 7755);
      connect(udpSocket, SIGNAL(readyRead()),
              this, SLOT(readPendingDatagrams()));
  }
  

2.1 客户端示例:

网络编程都需添加network(后面不再提醒)

widget.h 

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTextEdit>
#include <QLineEdit>
#include <QPushButton>
#include <QUdpSocket>
#include <QHostAddress>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void senddata()
    {
        udpsock->writeDatagram(le->text().toStdString().c_str(), QHostAddress("192.168.31.124"), 8888);
    }

    void recvdata()
    {
        QByteArray datagram;
        datagram.resize(udpsock->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        udpsock->readDatagram(datagram.data(), datagram.size(),
                                          &sender, &senderPort);
        te->append(datagram);
    }
public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QTextEdit *te;
    QLineEdit *le;
    QPushButton *pb;

    QUdpSocket *udpsock;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QVBoxLayout>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    te = new QTextEdit;
    le = new QLineEdit;
    pb = new QPushButton("send");
    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(te);
    vbox->addWidget(le);
    vbox->addWidget(pb);
    setLayout(vbox);

    udpsock = new QUdpSocket;

    connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
    connect(udpsock, SIGNAL(readyRead()), this, SLOT(recvdata()));
}

Widget::~Widget()
{

}

2.2 服务端

添加network

udpserver.h

#ifndef UDPSERVER_H // 如果UDPSERVER_H没有被定义
#define UDPSERVER_H // 定义UDPSERVER_H

#include <QObject> // 包含QObject的头文件,QObject是所有Qt对象的基类
#include <QUdpSocket> // 包含QUdpSocket的头文件,用于UDP通信
#include <QDebug> // 包含QDebug的头文件,用于在调试时输出信息

// 声明udpServer类,继承自QObject
class udpServer : public QObject
{
    Q_OBJECT // 启用Qt的信号和槽机制
public:
    explicit udpServer(QObject *parent = 0); // 构造函数,explicit防止隐式转换,可选的parent参数默认为0
    void init() // 初始化函数
    {
        udpSocket = new QUdpSocket(this); // 创建QUdpSocket对象
        udpSocket->bind(QHostAddress::AnyIPv4, 8888); // 绑定到任意IPv4地址的8888端口

        // 连接QUdpSocket的readyRead信号到本类的readPendingDatagrams槽,当有数据可读时触发
        connect(udpSocket, SIGNAL(readyRead()),
                      this, SLOT(readPendingDatagrams()));
        qDebug()<<"init...."; // 使用QDebug输出初始化信息
    }
signals: // 信号部分,此处未定义任何信号

public slots: // 槽部分
    void readPendingDatagrams() // 当有数据待读取时,会调用此函数
    {
        while (udpSocket->hasPendingDatagrams()) { // 循环处理所有待读取的数据报
                  QByteArray datagram; // 用于存储接收到的数据报
                  datagram.resize(udpSocket->pendingDatagramSize()); // 调整大小以匹配待读取数据报的大小
                  QHostAddress sender; // 发送者的地址
                  quint16 senderPort; // 发送者的端口

                  // 读取数据报,并保存发送者的地址和端口
                  udpSocket->readDatagram(datagram.data(), datagram.size(),
                                          &sender, &senderPort);

                  //processTheDatagram(datagram); // 处理数据报的函数
                  qDebug()<<"recv: "<<datagram; // 使用QDebug输出接收到的数据报

                  // 将接收到的数据报原样发送回去
                  udpSocket->writeDatagram(datagram.data(), datagram.size(),
                                           sender, senderPort);
              }
    }

private:
    QUdpSocket *udpSocket; // 指向QUdpSocket对象的指针
};

#endif // UDPSERVER_H // 结束预处理器指令

udpserver.cpp

#include "udpserver.h"

udpServer::udpServer(QObject *parent) : QObject(parent)
{

}

main.cpp

#include <QCoreApplication>
#include <udpserver.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    udpServer server;
    server.init();

    return a.exec();
}

最终效果:

3 TCP

框架

客户端:
mytcpsock = new QTcpSocket;
Mytcpsock->connectToHost(
QHostAddress("192.168.4.222"), 8888);

connect(mytcpsock, SIGNAL(readyRead()), this, SLOT(read_data()));

服务器:
Server::Server(QObject *parent) : QObject(parent)
{
    tcpserver = new QTcpServer;
    tcpserver->listen(QHostAddress::AnyIPv4, 8888);

    connect(tcpserver, SIGNAL(newConnection()),
		 this, SLOT(new_client()));
    tcpserver->waitForNewConnection();
}

3.1 客户端

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QTcpSocket>

class Widget : public QWidget
{
    Q_OBJECT
public slots:
    void senddata()
    {
        tcpsocket->write(le->text().toStdString().c_str());
    }
    void recvdata()
    {
        QByteArray buf = tcpsocket->readAll();
        te->append(buf);
    }


public:
    Widget(QWidget *parent = 0);
    ~Widget();
private:
    QLineEdit *le;
    QPushButton *pb;
    QTextEdit *te;

    QTcpSocket *tcpsocket;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QVBoxLayout>
#include <QHostAddress>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    le = new QLineEdit;
    pb = new QPushButton("senddata");
    te = new QTextEdit;

    QVBoxLayout *vbox = new QVBoxLayout;
    vbox->addWidget(te);
    vbox->addWidget(le);
    vbox->addWidget(pb);

    setLayout(vbox);

    tcpsocket = new QTcpSocket;
    //connect to server
    tcpsocket->connectToHost(QHostAddress("192.168.1.155"), 8888);

    connect(pb, SIGNAL(clicked(bool)), this, SLOT(senddata()));
    connect(tcpsocket, SIGNAL(readRead()), this, SLOT(recvdata()));

}

Widget::~Widget()
{

}

main.cpp

#include "widget.h"
#include <QApplication>

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

    return a.exec();
}

3.2 服务端

tcpServer.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>

class TcpServer : public QObject
{
    Q_OBJECT // 启用Qt的信号和槽机制
public:
    explicit TcpServer(QObject *parent = 0);
public slots:
    void newConnected()
    {
        qDebug() << "connected";
        clientsock = ser->nextPendingConnection(); //得到客户端
        connect(clientsock, SIGNAL(readyRead()), this, SLOT(recvData()));
    }

    void recvData()
    {
        QByteArray buf = clientsock->readAll();
        qDebug()<<"recv:"<<buf;
        clientsock->write(buf);
    }

private:
    QTcpServer *ser;
    QTcpSocket *clientsock;

};

#endif // TCPSERVER_H

tcpServer.cpp

#include "tcpServer.h"

TcpServer::TcpServer(QObject *parent) : QObject(parent)
{
    ser = new QTcpServer;
    ser->listen(QHostAddress::AnyIPv4, 8888);  //监听端口

    connect(ser, SIGNAL(newConnection()), this, SLOT(newConnected()));  //当新客户端来了与槽函数newConnected挂接上
    ser->waitForNewConnection(); //开启监听

}

 main.cpp

#include <QCoreApplication>
#include "tcpserver.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TcpServer server;

    return a.exec();
}

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

4IOT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值