5、QT的使用——TCP客户端和服务器

一、TCP

服务器:socket、bind、listen、accept、send/recv

客户端:socket、connect(对应服务器的accept)、send/recv

二、TCP客户端

1、qt中所有跟网络相关的必须添加network 

2、创建tcp对象

(1)在头文件中

#include <QTcpSocket>
#include <QHostAddress>//主机地址
#include <QMessageBox>
#include <QDebug>
#include <chat.h>

private:
    Ui::Widget *ui;
    QTcpSocket *socket;

(2)widget.cpp构造函数

socket = new QTcpSocket;   //创建socket对象

(3)点击连接时,获取文本框的内容 

void Widget::on_connectButton_clicked()
{
    //获取ip地址和端口号
    QString IP = ui->ipLineEdit->text();
    QString port = ui->portLineEdit->text();

    //连接服务器
    //用ip构造一个QHostAddress对象,并将port转换成短整形
    socket->connectToHost(QHostAddress(IP), port.toShort());

    //连接服务器成功,socket对象会发出信号,判断这个信号有没有发出即可
    connect(socket, &QTcpSocket::connected, [this]()
    {
        QMessageBox::information(this, "连接提示", "连接服务器成功");

        this->hide();
        Chat *c = new Chat(socket);    //堆空间创建
        c->show();
    });

    //连接断开,socket会发出信号
    connect(socket, &QTcpSocket::disconnected, [this]()
    {
        QMessageBox::warning(this, "连接提示", "连接异常 网络断开");
    });
}

(4)获取的数据从终端发出:

#include <QDebug>
qDebug()<<IP;

三、TCP服务器

服务器有对象,客户端没有对象,只需要有个socket即可

1、头文件中创建一个server指针

#include <QTcpServer>
#include <QTcpSocket>
#include <mythread.h>

#define PORT    8000
QTcpServer *server;

2、widget.cpp

(1)构造函数——监听等待客户端发起连接

    server = new QTcpServer;//创建服务器对象

    //此处不需要绑定,直接监听即可
    //监听客户端(端口号和网卡)
    server->listen(QHostAddress::AnyIPv4, PORT);

    //客户端发起连接,server发出信号,
    connect(server, &QTcpServer::newConnection, this, &Widget::newClientHandler);

(2)构造函数——建立TCP连接、获取客户端的端口号和地址并显示在界面上

void Widget::newClientHandler()
{
    //建立TCP连接
    QTcpSocket *socket = server->nextPendingConnection();
    //socket->peerAddress();   //获取客户端地址(地址保存在连接之中)
    //socket->peerPort();      //获取客户端的端口号

    ui->ipLineEdit->setText(socket->peerAddress().toString());
    ui->portLineEdit->setText(QString::number(socket->peerPort()));
}

四、建立新窗口

1、启动新的窗口——连接成功后,原窗口隐藏,显示新的界面

        this->hide();
        Chat *c = new Chat(socket);    //堆空间创建
        c->show();

2、新界面

(1)清空健——将输入信息清空

void Chat::on_clearButton_clicked()
{
    ui->lineEdit->clear();
}

(2)启动新的界面

首先在widget.h中包含#include<chat.h>

        this->hide();//把当前的界面隐藏
        Chat *c = new Chat(socket);    //启动新的界面,堆空间创建
        c->show();

不能是Chat c;因为这样在栈空间创建,函数结束后,就没有了

(3)chat.cpp——创建chat的界面,即清空、发送健、和文本框

void Chat::on_clearButton_clicked()//清空健
{        ui->lineEdit->clear();      }

void Chat::on_sendButton_clicked(){//发送健
    QByteArray ba;
    ba.append(ui->lineEdit->text());
    socket->write(ba);
}

void Chat::recvInfoSlot()//获取的文本
{    ui->recvLineEdit->setText(QString(socket->readAll()));    }

(4)在服务器处添加获取客户端信息的代码

void Widget::clientInfoSlot()
{
    //sender捕捉信号,获取信号的发出者
    QTcpSocket *s = (QTcpSocket *)sender();
    ui->mainLineEdit->setText(QString(s->readAll()));
}

void Widget::newClientHandler()中
    //服务器收到客户端发送的信息,socket发出readyread信号
    connect(socket, &QTcpSocket::readyRead, this, &Widget::clientInfoSlot);

五、多线程

1、创建文件——要继承Object类

在mythread.h中,myThread要继承Qobject类和QThread类

包含头文件:#include <QThread>

调用t->start()时,运行的是run,该实验要重写run

public:
    explicit myThread(QTcpSocket *s);
    void run();     //线程处理函数

2、widget.cpp——一旦建立连接,就要启动线程

    //启动线程
    myThread *t = new myThread(socket);   //创建线程对象,要把对象传过去
    t->start();                           //开始线程

    connect(t, &myThread::sendToWidget, this, &Widget::threadSlot);

3、mythread.cpp

myThread::myThread(QTcpSocket *s){
    socket = s;      }

void myThread::run(){
    connect(socket, &QTcpSocket::readyRead, this, &myThread::clientInfoSlot);
}

//不能在其他类里面操作界面
void myThread::clientInfoSlot(){
    //qDebug() << socket->readAll();
    QByteArray ba = socket->readAll();//把所有数据读出来
    emit sendToWidget(ba);      //发送信号
}

五、自定义信号

服务器后台的线程收到的数据,然后线程把数据送到窗口上面

(1)mythread.cpp获取信息

    QByteArray ba = socket->readAll();//把所有数据读出来
    emit sendToWidget(ba);      //发送信号,没有具体发哦是那个给谁,谁需要自己来拿

(2)widget.cpp中获取信号的信息

connect(t, &myThread::sendToWidget, this, &Widget::threadSlot);

void Widget::threadSlot(QByteArray b)
{
    ui->mainLineEdit->setText(QString(b));
}
将发送的信息接收,并显示在文本框上

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值