QT实现TCP通信

3 篇文章 0 订阅
3 篇文章 0 订阅

代码如下

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;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

房东不养猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值