代码如下
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;
}
?
|