代码如下
tcp_thread.h
#ifndef TCP_THREAD_H
#define TCP_THREAD_H#include
#include
#include
#include
#include
#include 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 bytes_queue;
QQueue 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
#include
#include "tcp_thread.h"
#include
#includeQT_BEGIN_NAMESPACE
namespace Ui { class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{
Q_OBJECTpublic:
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 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()<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()<
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
#include
#include
#include
#include 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 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;
}
【QT|QT实现TCP通信】
推荐阅读
- [Qt学习笔记]Qt实现多摄像头的识别、显示、截图、分辨率帧率设置等功能
- C语言必学的数据结构|还在抱怨数据结构难? 一文带你搞懂如何AC算法题(2022版)
- C语言|C语言开发专题(56个案例)-程序设计 - 课程设计
- tcp/ip|TCP、IP 、HTTP——深入学习TCP协议
- 编程题|C语言——动态分配数组malloc的使用及读走回车换行符问题
- 初学至学会C++|初阶C++—— 第三节—— 动态内存管理 初识模板
- C|C语言——知识点汇总
- C语言|C语言——运算符
- C语言经典例题|【C语言典例】——day11(统计二进制中1的个数)