(QT)TCP与UDP编程

目录

一、TCP

1、QTcpServer

1.1概念

1.2 添加头文件

1.3 主要代码

2、TCPClient

1、实现步骤

2、主要代码

二、UDP

 1、实现步骤

2、 涉及头文件

3、 主要实现代码


需要添加网络模块

QT       += core gui network

一、TCP

1、QTcpServer

1.1概念

QTcpServer 是 Qt 中的一个网络模块,它提供了基于 TCP 协议的服务器端编程接口,可以实现服务器端的网络通信。通过 QTcpServer,我们可以很方便地创建一个 TCP 服务器,接受来自客户端的连接请求,并与客户端进行数据通信。

在使用 QTcpServer 时,我们需要实现它的槽函数来处理客户端连接、数据读取、客户端断开等事件。QTcpServer 提供了一些信号,如 newConnection()、disconnected() 和 readyRead() 等,用于通知我们这些事件的发生。我们可以通过连接这些信号来实现服务器的各种功能,如接受客户端连接、读取客户端数据、向客户端发送数据等。

除了 QTcpServer,Qt 还提供了其他一些网络模块,如 QUdpSocket 和 QNetworkAccessManager 等,它们分别对应于基于 UDP 协议的数据通信和 HTTP 协议的网络通信。

1.2 添加头文件

#include <QTcpServer>
#include <QTcpSocket>

1.3 主要代码

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("TcpServer");
    tcpServer = new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(mNewConnetion()));
}

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

void Widget::mNewConnetion()
{
    //与客户端链接                       从连接队列中获取下一个连接对象
    QTcpSocket *tmpTcpSocket=tcpServer->nextPendingConnection();

    //打印客户端的ip 端口等信息
    QString ipAddr=tmpTcpSocket->peerAddress().toString(); //客户端ip地址
    quint16 port=tmpTcpSocket->peerPort(); //客户端端口号
    ui->textBrowser->append("客户端的ip:" + ipAddr);
    ui->textBrowser->append("客户端的port:" + QString::number(port));

    connect(tmpTcpSocket,SIGNAL(readyRead()),this,SLOT(receiveMessages()));
    connect(tmpTcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}

void Widget::receiveMessages()
{
    QTcpSocket *tmpTcpSocket=(QTcpSocket*)sender();
    ui->textBrowser->append("客户端: "+tmpTcpSocket->readAll());
}

void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
    QTcpSocket *tmpTcpSocket=(QTcpSocket*)sender();

    switch(state) {
    case QAbstractSocket::UnconnectedState://表示未连接状态,即还没有尝试建立连接
        ui->textBrowser->append("客户端断开连接");
        //delete tmpTcpSocket;//不能在这样删除,可能其他地方还在用tmpTcpSocket而导致程序异常
        tmpTcpSocket->deleteLater();//延时删除,其他地方也没用之后再释放资源
        break;

    case QAbstractSocket::HostLookupState:     break;//表示正在进行主机名解析的状态,即正在将主机名转换为IP地址
    case QAbstractSocket::ConnectingState:     break;//表示正在尝试连接的状态
    case QAbstractSocket::ConnectedState:      break;//表示已连接的状态
    case QAbstractSocket::BoundState:          break;//表示已绑定到一个本地地址的状态,等待连接请求
    case QAbstractSocket::ListeningState:      break;//表示正在监听连接请求的状态
    case QAbstractSocket::ClosingState:        break;//表示正在关闭连接的状态
    }
}



void Widget::on_pushButton_3_clicked()
{
    QList <QTcpSocket *> socketList = tcpServer->findChildren<QTcpSocket *>();
    qDebug()<<"tcpSocket数量:"<<socketList.count()<<endl;
    if (socketList. count() == 0)
    {
        ui->textBrowser-> append("当前没有客户端连接,请先与客户端连接! ");
        return;
    }


    /*foreach(QTcpSocket *tmpTcpSocket,socketList){
        //服务端向每个客户端发送消息
        tmpTcpSocket->write(ui->lineEdit->text().toUtf8());
    }*/
    for(auto e:socketList)
    {
        e->write(ui->lineEdit->text().toUtf8());
    }
    ui-> textBrowser->append("服务端已发送: " + ui->lineEdit->text());
}

void Widget::on_pushButton_clicked()
{
    ui->textBrowser->append("服务端:绑定的ip地址和端口: 192.168.1.59, 9999") ;
    //绑定ip和端口
    tcpServer->listen(QHostAddress("192.168.230.130"),9999);
}

void Widget::on_pushButton_4_clicked()
{
    ui->textBrowser->clear();
}

void Widget::on_pushButton_2_clicked()
{
    tcpServer->close();
}

2、TCPClient

1、实现步骤

  1. 创建QTcpSocket对象,该对象用于建立TCP连接并进行通信。
  2. 连接到服务器
  3. 监听连接的信号,以确定是否成功建立了连接
  4. 实现连接成功时的槽函数
  5. 实现从服务器接收数据的槽函数
  6. 发送数据给服务器
  7. 断开连接

2、主要代码

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("TcpClient");
    ui->pushButton_2->setEnabled(false);

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(reciveMessages()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}

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

void Widget::reciveMessages()
{
    ui->textBrowser->append("服务端: " + tcpSocket->readAll());
}

void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
    switch (state) {
    case QAbstractSocket::UnconnectedState:
        ui->textBrowser->append("与服务端断开连接");
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(false);
        break;
    case QAbstractSocket::ConnectedState:
        ui->textBrowser-> append("已连接服务端");
        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(true);
        break;

    default:
        break;
    }
}

void Widget::on_pushButton_3_clicked()
{
    //发送消息
    if(tcpSocket->state()==QAbstractSocket::ConnectedState){

        tcpSocket->write(ui->lineEdit->text().toUtf8());
        ui-> textBrowser->append("客户端已发送: " + ui->lineEdit->text()) ;
    }
    else
        ui->textBrowser->append("请先与服务端连接!");
}

void Widget::on_pushButton_clicked()
{
    //连接服务端,指定服务端ip 和 port
    tcpSocket->connectToHost(QHostAddress("192.168.230.130"),9999);
    ui->textBrowser->append("客户端:连接的ip地址和端口: 192.168.1.59, 9999");

}

void Widget::on_pushButton_2_clicked()
{
    //断开连接
    tcpSocket->disconnectFromHost();
}

void Widget::on_pushButton_4_clicked()
{
    ui->textBrowser->clear();
}

二、UDP

 1、实现步骤

①创建一个 QUdpSocket 对象,可以使用 QUdpSocket::QUdpSocket() 构造函数来创建。

②使用 QUdpSocket::bind() 函数将 QUdpSocket 对象绑定到指定的端口上,这样就可以接收到客户端发送的数据了。

③在 QUdpSocket 对象的 readyRead() 信号中,使用 QUdpSocket::readDatagram() 函数读取客户端发送的数据。

④对接收到的数据进行处理,可以使用 QUdpSocket::writeDatagram() 函数将处理结果返回给客户端。

⑤创建一个 UDP 客户端,也是使用 QUdpSocket 对象来实现。在客户端中使用 QUdpSocket::writeDatagram() 函数发送数据到服务器。

⑥在 UDP 通信完成后,需要关闭服务器和客户端,可以使用 QUdpSocket::close() 函数来关闭 QUdpSocket 对象。

2、 涉及头文件

#include <QTcpSocket>
#include <QHostAddress>

3、 主要实现代码

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("TcpClient");
    ui->pushButton_2->setEnabled(false);

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(reciveMessages()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(mStateChanged(QAbstractSocket::SocketState)));
}

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

void Widget::reciveMessages()
{
    ui->textBrowser->append("服务端: " + tcpSocket->readAll());
}

void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
    switch (state) {
    case QAbstractSocket::UnconnectedState:
        ui->textBrowser->append("与服务端断开连接");
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(false);
        break;
    case QAbstractSocket::ConnectedState:
        ui->textBrowser-> append("已连接服务端");
        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(true);
        break;

    default:
        break;
    }
}

void Widget::on_pushButton_3_clicked()
{
    //发送消息
    if(tcpSocket->state()==QAbstractSocket::ConnectedState){

        tcpSocket->write(ui->lineEdit->text().toUtf8());
        ui-> textBrowser->append("客户端已发送: " + ui->lineEdit->text()) ;
    }
    else
        ui->textBrowser->append("请先与服务端连接!");
}

void Widget::on_pushButton_clicked()
{
    //连接服务端,指定服务端ip 和 port
    tcpSocket->connectToHost(QHostAddress("192.168.230.130"),9999);
    ui->textBrowser->append("客户端:连接的ip地址和端口: 192.168.1.59, 9999");

}

void Widget::on_pushButton_2_clicked()
{
    //断开连接
    tcpSocket->disconnectFromHost();
}

void Widget::on_pushButton_4_clicked()
{
    ui->textBrowser->clear();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zhang丶&|!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值