QT网络编程——TCP服务器和客户端通信


网络编程有TCP和UDP。

TCP编程需要用到两个类:
1、QTcpServer——实现服务器的端口监听,可以提供一种服务。
2、QTcpSocket——实现套接字类,有消息的封装,可以读取和写入。

注意: QTcpServer、和QTcpSocket两个类在服务器中会用到,而客户端中只用到QTcpSocket类

一、服务器端

1、QT中TCP服务器的开发思路

1、开启服务器开启端口服务:建立QTcpServer对象,并用其中的listen()方法就可以开启指定的端口。

tcpServer->listen(QHostAddress::Any,ui->lineEdit_port->text().toUInt());    //服务器对端口号进行监听

2、当有客户端连接到服务器时,系统会接收到newConnection信号,所以需要在对应的槽函数中获取用于通信的套接字(QTcpServer的nextPendingConnection()函数获取套接字)。

tcpSocket = tcpServer->nextPendingConnection();     //获取与客户端进行通信的套接字

3、客户端有数据过来,则会产生一个readyRead信号,从对应的槽函数中通过套接字的readAll()等相关函数读取数据。

buf = QString(tcpSocket->readAll());    //用套接字读取客户端发来的数据

4、通过套接字的write()函数向客户端发送数据。

tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());

2、QT服务器界面设计

在这里插入图片描述

3、QT服务器代码实现

(1)、添加模块和和头文件

1)在pro文件中添加一行内容:QT += network
2)在widget.h头文件中添加需要用到的服务器头文件

#include "QTcpServer"
#include "QTcpSocket"

(2)在widget构造函数中创建QTcpServer、和QTcpSocket对象

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

    tcpServer = new QTcpServer(this);   //创建一个服务器类
    tcpSocket = new QTcpSocket(this);   //创建一个socket类
}

(3)写”启动服务器"按键的槽函数(实现按下就启动服务器,再次按下就关闭服务器)

服务器实现监听;将newConnection信号和槽函数进行绑定

void Widget::on_pushButton_startOrStop_clicked()
{
    if(ui->pushButton_startOrStop->text() == "启动服务器")
    {
     tcpServer->listen(QHostAddress::Any,ui->lineEdit_port->text().toUInt());    //服务器对端口号进行监听
     connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_slot())); //有网络用户连接进来,就会执行槽函数
     
     ui->pushButton_startOrStop->setText("关闭服务器");
     ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/server_open.png);");
    }
    else
    {
        tcpServer->close();
        ui->pushButton_startOrStop->setText("启动服务器");
        ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/server_close.png);");
    }
}

(4)有用户连接服务器时,系统收到newConnection信号,这里写对应的槽函数
进入这个槽函数表示有用户连接进来了,所以获取该套接字;并判断是否接收客户端数据(readyRead信号和槽函数绑定)
在头文件中声明槽函数

private slots:
    void newConnection_slot();

实现槽函数功能

void Widget::newConnection_slot()
{
    tcpSocket = tcpServer->nextPendingConnection();     //获取与客户端进行通信的套接字
    ui->label_clientIp->setText(tcpSocket->peerAddress().toString());   //获取客户端的IP地址

    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot())); //客户端有数据到达服务器,就会产生readyRead信号
}

(5)服务器接收到数据后,会产生readyRead信号,这里实现对应槽函数功能

在头文件中声明槽函数

private slots:
    void readyRead_slot();

实现槽函数功能:接收来自客户端的数据

void Widget::readyRead_slot()
{
    QString buf;
    buf = QString(tcpSocket->readAll());    //用套接字读取客户端发来的数据
    ui->plainTextEdit_receive->appendPlainText(buf);
}

(6)实现“发送”按钮的槽函数

void Widget::on_pushButton_send_clicked()
{
    tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());
}

二、客户端

1、QT中TCP客户端的开发思路

1、创建QTcpSocket对象,并用connectToHost()函数通过IP和端口号连接服务器。

tcpSocket = new QTcpSocket(this);
tcpSocket->connectToHost(ui->lineEdit_ip->text(),ui->lineEdit_port->text().toUInt());   //根据IP地址和端口号连接服务器

2、客户端成功连接上服务器,系统会产生connected信号。(所以需要将信号和槽函数进行绑定)

connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_slot()));   //客户端连接服务器成功后会产生connected信号

3、客户端收到服务器发送来的数据,会产生readyRead信号,在connected信号对应的槽函数中,将readyRead信号和对应的槽函数进行绑定。

connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot()));     //和服务器连接成功后,就需要就收服务器发送过来的数据了,

4、通过套接字对象读取服务器发来的数据。(用readall()等函数)

tcpSocket->readAll();      //从套接字中读取服务器发来的数据

5、通过套接字向服务器发送数据。(用write()函数)

tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());       //向服务器发送数据

2、QT客户端界面设计

在这里插入图片描述

3、QT客户端代码实现

(1)、添加模块和和头文件

1)在pro文件中添加一行内容:QT += network
2)在widget.h头文件中添加需要用到的服务器头文件

#include "QTcpSocket"

(2)在widget构造函数中创建QTcpSocket对象

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

    tcpSocket = new QTcpSocket(this);   //创建一个socket类
}

(3)实现“连接服务器”按钮的槽函数

void Widget::on_pushButton_startOrStop_clicked()
{
    if(ui->pushButton_startOrStop->text() == "连接服务器")   //表示可以连接服务器
        {

            tcpSocket->connectToHost(ui->lineEdit_ip->text(),ui->lineEdit_port->text().toUInt());   //根据IP地址和端口号连接服务器
            connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_slot()));   //客户端连接服务器成功后会产生connected信号

            ui->pushButton_startOrStop->setText("断开连接");    //修改按键的提示字,为下次关闭做准备
            ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/client_open.png);");     //修改标签的样式表
        }
    else        //表示可以断开和服务器的连接
        {
            tcpSocket->close();     //断开和服务器的连接

            ui->pushButton_startOrStop->setText("连接服务器");   //修改按键的提示字,为下次连接做准备
            ui->label_startOrClose->setStyleSheet("border-image: url(:/Pic/client_close.png);");
        }

}

(4)客户端连接到服务器会触发connected信号,实现对应槽函数

void Widget::connected_slot()
{
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_slot()));     //和服务器连接成功后,就需要就收服务器发送过来的数据了,
                                                                            //如果客户端收到发送过来的数据,系统会产生readyRead信号
}

(5)客户端收到服务器发送过来的数据会触发readyRead信号,实现对应槽函数

void Widget::readyRead_slot()
{
    //这里是读取所有的信息,后期建议修改为分片读取,防止大文件一次读取不完
    ui->plainTextEdit->appendPlainText(QString(tcpSocket->readAll()));      //从套接字中读取服务器发来的数据
}

(6)为“发送”按钮实现槽函数

void Widget::on_pushButton_send_clicked()
{
    //tcpSocket->write(ui->lineEdit_send->text().toLocal8Bit().data());       //向服务器发送数据
    tcpSocket->write(ui->lineEdit_send->text().toUtf8());     //可以接收到服务器发送过来的汉字
}

附工程源文件下载链接:
QT客户端+服务器源码下载

  • 24
    点赞
  • 167
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

掏一淘哆啦A梦的奇妙口袋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值