IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> QT实现TCP通信 -> 正文阅读

[网络协议]QT实现TCP通信

代码如下

tcp_thread.h

#ifndef TCP_THREAD_H
#define TCP_THREAD_H

#include <QThread>
#include <QHostAddress>
#include <QQueue>
#include <QMutex>
#include <QTcpSocket>
#include <QTcpServer>

class Tcp_Thread : public QThread
{
    Q_OBJECT
public:
    explicit Tcp_Thread(QHostAddress ip,QString port,QObject *parent = nullptr);
    ~Tcp_Thread();

    bool start_flag; //线程工作标志位
    bool connect_flag; //tcp连接标志位
    bool recv_flag; //保存接收数据到队列标志位
    QQueue<QByteArray> bytes_queue;
    QQueue<QString> msg_queue;

    QTcpSocket *socket; //套接字
    QTcpServer *server; //
    QHostAddress client_ip;
    qint16 client_port;
    bool c;

    void stop(); //暂停线程
    void go_on(); //继续线程
    void new_client_connect();

protected:
    void run();

signals:
    void signal_msg();
private:
    QMutex mutex; //互斥量,用来暂停和继续线程

private slots:
    void read_tcp();
    void socket_disconnect();

};

#endif // TCP_THREAD_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QHostAddress>
#include "tcp_thread.h"
#include<QTcpServer>
#include<QTcpSocket>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    Tcp_Thread *tcp_thread;

    QHostAddress get_local_host_ip();
    void is_ui_visiable(bool state);

private slots:
    void close_thread();
    void display_udp_frame();
    void print_tcp_msg();
    void slotRecv(char *buf, int len);
    void on_btn_open_clicked();
    void on_btn_clear_clicked();
    void on_btn_send_clicked();
    void on_open_file_3_clicked();
};
#endif // WIDGET_H

tcp_thread.cpp

#include "tcp_thread.h"
#include <QDebug>

Tcp_Thread::Tcp_Thread(QHostAddress ip,QString port,QObject *parent) : QThread(parent)
{
    start_flag = true; //线程工作标志位
    connect_flag = false; //TCP连接标志位
    recv_flag = false;
    server = new QTcpServer(); //新建一个对象
    server->listen(ip, port.toInt()); //监听端口,等待客户端连接
      qDebug()<<"步骤A";
    connect(server,&QTcpServer::newConnection,this,&Tcp_Thread::new_client_connect);
     qDebug()<<"步骤E";
//    c=connect(server,&QTcpServer::newConnection,this,&Tcp_Thread::new_client_connect);
//    qDebug()<<c<<endl;
}


void Tcp_Thread::run()
{
    QByteArray data_temp;

    while(start_flag)
    {
        mutex.lock();
        if(!bytes_queue.isEmpty())
        {
            data_temp = bytes_queue.dequeue();
                  qDebug()<<"步骤B";
            msg_queue.enqueue(QString(data_temp));
            emit signal_msg();
        }
        mutex.unlock();
    }
}

void Tcp_Thread::new_client_connect()
{
    socket = server->nextPendingConnection(); //获取客户端套接字
    client_ip = socket->peerAddress();
    client_port = socket->peerPort(); //此时为空
    connect(socket,SIGNAL(readyRead()),this,SLOT(read_tcp()));
    connect(socket, SIGNAL(disconnected()),this, SLOT(socket_disconnect()));
  qDebug()<<"步骤C";
    connect_flag = true;
    msg_queue.enqueue(QString("上线 [%1]").arg(client_ip.toString()));
    emit signal_msg();
//    socket_disconnect();
}

//读取客户端发送来的数据
void Tcp_Thread::read_tcp()
{
    QByteArray buffer;
    buffer = socket->readAll();
     qDebug()<<"步骤D";
    if(recv_flag)
    {
        bytes_queue.enqueue(buffer);
         qDebug()<<buffer;

    }
}

void Tcp_Thread::socket_disconnect()
{
    connect_flag = false;
    msg_queue.enqueue(QString("已断开!"));
    emit signal_msg();
}

void Tcp_Thread::stop()
{
    mutex.lock();
}

void Tcp_Thread::go_on()
{
    mutex.unlock();
}

Tcp_Thread::~Tcp_Thread()
{

}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDir>
#include <QNetworkInterface>
#include <QFileDialog>
#include <QThread>
#include<QDebug>
#include<QImage>
#include<QMessageBox>
#include <windows.h>


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

    //作为服务端,获取本机ip地址,将TCP端口设为9999
    QHostAddress local_ip = get_local_host_ip();
    QString tcp_port = "9999";
  // QString udp_port = "9999";

 //   ui->lineEdit_path->setText(QDir::currentPath()+"/"); //添加项目文件路径到控件

    ui->ip_local->setText(local_ip.toString());

    ui->port_tcp->setText(tcp_port);
    is_ui_visiable(false);

    //新建TCP对象和thread对象
    tcp_thread = new Tcp_Thread(local_ip,tcp_port);
    connect(tcp_thread,&Tcp_Thread::signal_msg,this,&Widget::print_tcp_msg);

    //新建udp对象和thread对象

    //udp_thread = new Udp_Thread(local_ip,udp_port);
   // connect(udp_thread, &Udp_Thread::signal_img, this, &Widget::display_udp_frame); //接收线程信号

    connect(this, &Widget::destroyed, this, &Widget::close_thread); //线程跟随窗口退出

    tcp_thread->start();
   // udp_thread->start();
    tcp_thread->stop();
   //udp_thread->stop(); //暂停udp线程,等到开启接收画面后再开启工作
    ui->record->setText("等待客户端连接...");
}




//显示TCP数据
void Widget::print_tcp_msg()
{
    if(!tcp_thread->msg_queue.isEmpty())
    {
        ui->record->setTextColor(QColor::fromRgb(255,0,0));
        ui->record->append("client:"+tcp_thread->msg_queue.dequeue());
        ui->record->setTextColor(QColor::fromRgb(0,0,0));
        if(!tcp_thread->connect_flag)
        {
            on_btn_open_clicked();
            ui->record->setText("等待客户端连接...");
        }
    }
}

//关闭线程
void Widget::close_thread()
{
    tcp_thread->go_on();
    tcp_thread->start_flag = false; //停止线程
    tcp_thread->quit();
    tcp_thread->wait(); //等待线程处理完手头工作
    if(tcp_thread->connect_flag)
    {
        tcp_thread->socket->abort();
        tcp_thread->server->close();
    }



}


//开启监听
void Widget::on_btn_open_clicked()
{
    if(ui->btn_open->text().toUtf8() == "监听")
    {
        if(tcp_thread->connect_flag)
        {
            ui->btn_open->setText("关闭");
            is_ui_visiable(true); //控件使能

            tcp_thread->go_on(); //继续tcp线程

            tcp_thread->recv_flag = true;
        }
        else
        {
            ui->record->append("无客户端连接!");
        }
    }
    else if(ui->btn_open->text().toUtf8() == "关闭")
    {
        ui->btn_open->setText("监听");

        tcp_thread->recv_flag = false;
        is_ui_visiable(false); //控件失能

        tcp_thread->stop(); //暂停udp线程
        ui->record->clear();
    }
}

void Widget::on_btn_send_clicked()
{
    QString msg = ui->textEdit_send->toPlainText();
    tcp_thread->socket->write(msg.toUtf8());
    tcp_thread->socket->flush();
    ui->record->setTextColor(QColor::fromRgb(0,0,255));
    ui->record->append("server: "+msg);
    ui->record->setTextColor(QColor::fromRgb(0,0,0));
}


//清空接受区
void Widget::on_btn_clear_clicked()
{
    ui->record->clear();
    ui->textEdit_send->clear();
}

//控件是否可操作
void Widget::is_ui_visiable(bool state)
{
//    ui->btn_snap->setEnabled(state);
//    ui->btn_screen_cap->setEnabled(state);
//    ui->lineEdit_path->setEnabled(state);
//    ui->btn_path_change->setEnabled(state);
//    ui->btn_jpg->setEnabled(state);
//    ui->btn_png->setEnabled(state);
    ui->btn_clear->setEnabled(state);
    ui->btn_send->setEnabled(state);
    ui->textEdit_send->setEnabled(state);
}



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

void Widget::on_open_file_3_clicked()
{
    QString filename;
    filename=QFileDialog::getOpenFileName(this,tr("选择图像"),"",tr("Images (*.png *.bmp *.jpg *.tif *.GIF )"));
    if(filename.isEmpty())
    {

         return;

    }
    else
    {
        QImage* img=new QImage;
        if(!( img->load(filename) ) ) //加载图像
        {
            QMessageBox::information(this,tr("打开图像失败"),tr("打开图像失败!"));
            delete img;
            return;
        }
       ui->origin_pic->setPixmap(QPixmap::fromImage(*img));
        ui->origin_pic->setStyleSheet("background: white;");  // 标签白色背景
        ui->origin_pic->setAlignment(Qt::AlignCenter);  // 图片居中
    }
}
//获取本机在局域网下的ip地址
QHostAddress Widget::get_local_host_ip()
{
  QList<QHostAddress> AddressList = QNetworkInterface::allAddresses();

  QHostAddress result;
  foreach(QHostAddress address, AddressList)
  {
      if(address.protocol() == QAbstractSocket::IPv4Protocol &&
         address != QHostAddress::Null &&
         address != QHostAddress::LocalHost)
      {
          if (address.toString().contains("127.0.")){
            continue;
          }

          if(address.toString().contains("192.168.31.")){
            result = address;
            break;
          }
      }
  }

  return result;
}

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:56:03  更:2022-03-08 22:57:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:48:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码