本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
阿里云开发者社区用户服务协议
》和
《
阿里云开发者社区知识产权保护指引
》。如果您发现本社区中有涉嫌抄袭的内容,填写
侵权投诉表单
进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
qDebug
(
)
<<
"Current OS is Linux"
;
#
elif
defined(Q_OS_WIN)
qDebug
(
)
<<
"Current OS is Windows"
;
#
else
qDebug
(
)
<<
"Unknown OS"
;
#
endif
QString folderName
=
"pic"
;
QString folderPath
=
QApplication
::
applicationDirPath
(
)
+
"/"
+
folderName
;
QDir
folder
(
folderPath
)
;
if
(
!
folder
.
exists
(
)
)
bool
success
=
folder
.
mkpath
(
"."
)
;
if
(
success
)
qDebug
(
)
<<
"文件夹创建成功"
;
qDebug
(
)
<<
"文件夹创建失败"
;
qDebug
(
)
<<
"文件夹已存在"
;
QDir
::
setCurrent
(
folderPath
)
;
AdClient w
;
w
.
show
(
)
;
return
a
.
exec
(
)
;
tcp_MSG.h 共用Tcp传输信息
#ifndef TCP_MSG_H
#define TCP_MSG_H
#include<QMetaType>
#define tcp_MSG_txt_NUM 256
#define tcp_MSG_city_NUM 32
#define tcp_MSG_weather_NUM 128
#define tcp_MSG_path_NUM 128
#define tcp_MSG_photo_NUM 1280*800
#pragma pack(1)
typedef struct
int type;
char txt[tcp_MSG_txt_NUM];
char city[tcp_MSG_city_NUM];
char area[tcp_MSG_city_NUM];
char weather[tcp_MSG_weather_NUM];
char fileName[tcp_MSG_path_NUM];
int index;
int allAd_Num;
int fileSize;
}tcp_MSG;
#pragma pack()
Q_DECLARE_METATYPE(tcp_MSG)
enum MsgType{
Init=0,
WEATHER,
MASSEGE,
VIDEO,
AD_add,
AD_delete,
Write_back,
#pragma pack(1)
typedef struct
int type;
int state;
char id[32];
}tcp_backMSG;
#pragma pack()
Q_DECLARE_METATYPE(tcp_backMSG)
#pragma pack(1)
typedef struct
int type;
char photo[tcp_MSG_photo_NUM];
}tcp_Image;
#pragma pack()
Q_DECLARE_METATYPE(tcp_Image)
#endif
adclient.h 客户端
#ifndef ADCLIENT_H
#define ADCLIENT_H
#include <QMainWindow>
#include "addate.h"
#include "adsocket.h"
#include "weather.h"
#include "rollmassege.h"
#include <QLabel>
#include <QProgressDialog>
#include "stdlib.h"
#include <QThread>
#include <QTimer>
#include <QFile>
#include <QMessageBox>
#include <QNetworkInterface>
#include <QTcpSocket>
#include <QHostAddress>
#include <QAbstractSocket>
#include <QLineEdit>
#include <QPushButton>
namespace Ui {
class AdClient;
class AdClient : public QMainWindow
Q_OBJECT
public:
explicit AdClient(QWidget *parent = 0);
~AdClient();
void saveFile();
void InitStatusBar();
QString GetLocalIP();
public slots:
void showImage(QImage);
void showProgressBar(int currentProgress,int finish);
void autoPlayTimeOut();
void GUI_WarningMsg(QString title,QString text,QString buttons,QString defaultButton);
void connectToServer();
private:
Ui::AdClient *ui;
AdDate *date;
AdSocket *socket;
Weather *weater;
RollMassege *rollmsg;
QProgressDialog *progress;
QTimer autoPlayTimer;
int index;
QLabel *mLocalIP;
QLabel *serverIP_lb;
QLineEdit *serverIP;
QLabel *serverPort_lb;
QLineEdit *serverPort;
QPushButton *connectTcp;
#endif
adclient.cpp 客户端
#include "adclient.h"
#include "ui_adclient.h"
#include <QDebug>
QMap<QString,QImage> qMapPicturePath;
AdClient::AdClient(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::AdClient)
ui->setupUi(this);
this->setWindowIcon(QIcon(":/client.jpg"));
date = new AdDate(ui->date_lb);
socket = new AdSocket;
weater = new Weather(ui->weather_lb);
rollmsg = new RollMassege(ui->msg_lb, ui->msg_lb);
connect(socket, SIGNAL(sig_showWeather(QString,QString,QString)), weater, SLOT(showWeather(QString,QString,QString)));
connect(socket, SIGNAL(sig_showTxt(QString)), rollmsg, SLOT(showTxt(QString)));
connect(socket, SIGNAL(sig_showImage(QImage)), this, SLOT(showImage(QImage)));
connect(socket, SIGNAL(sig_showProgressBar(int,int)), this, SLOT(showProgressBar(int,int)),Qt::QueuedConnection);
connect(socket, SIGNAL(GUI_WarningSignal(QString,QString,QString,QString)), this, SLOT(GUI_WarningMsg(QString,QString,QString,QString)));
date->start();
progress = nullptr;
autoPlayTimer.stop();
connect(&autoPlayTimer, SIGNAL(timeout()), this, SLOT(autoPlayTimeOut()));
InitStatusBar();
AdClient::~AdClient()
delete socket;
delete ui;
void AdClient::saveFile()
QString fileName=qMapPicturePath.lastKey();
qDebug()<<"lastKey:"<<fileName;
QImage image=qMapPicturePath.last();
image.save(fileName);
void AdClient::InitStatusBar()
mLocalIP=new QLabel(this);
mLocalIP->setMinimumWidth(230);
QString ip = GetLocalIP();
mLocalIP->setText("本地IP:"+tr("<font color=\"red\">%1</font>").arg(ip));
serverIP_lb=new QLabel(this);
serverIP_lb->setMinimumWidth(100);
serverIP_lb->setText("服务器IP:");
serverIP=new QLineEdit(this);
serverIP->setMinimumWidth(200);
serverIP->setInputMask("000.000.000.000");
serverPort_lb=new QLabel(this);
serverPort_lb->setMinimumWidth(60);
serverPort_lb->setText("Port:");
serverPort=new QLineEdit(this);
serverPort->setMinimumWidth(60);
serverPort->setPlaceholderText("8888");
connectTcp=new QPushButton("链接",this);
connectTcp->setMinimumWidth(100);
ui->statusBar->addWidget(mLocalIP);
ui->statusBar->addWidget(serverIP_lb);
ui->statusBar->addWidget(serverIP);
ui->statusBar->addWidget(serverPort_lb);
ui->statusBar->addWidget(serverPort);
ui->statusBar->addWidget(connectTcp);
connect(connectTcp, SIGNAL(clicked()), this, SLOT(connectToServer()));
QString AdClient::GetLocalIP()
QList<QHostAddress> list=QNetworkInterface::allAddresses();
foreach(QHostAddress address,list)
if(address.protocol()==QAbstractSocket::IPv4Protocol)
qDebug()<<address.toString();
return address.toString();
return "";
void AdClient::showImage(QImage image)
qDebug()<<"显示图片"<<__LINE__;
QPixmap pixmap=QPixmap::fromImage(image);
ui->video_lb->setScaledContents(true);
ui->video_lb->setPixmap(pixmap.scaled(ui->video_lb->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
qDebug()<<"图片数量:"<<qMapPicturePath.count();
qDebug()<<"定时器状态:"<<autoPlayTimer.isActive();
if(qMapPicturePath.count()>=2)
if(!autoPlayTimer.isActive()){
autoPlayTimer.start(5000);
index=0;
autoPlayTimer.stop();
if(qMapPicturePath.count()>=1)
void AdClient::showProgressBar(int currentProgress, int finish)
qDebug()<<"进度条显示"<<__LINE__;
if (!progress)
progress = new QProgressDialog("接收中....", "取消", 0, 100, this);
progress->setWindowModality(Qt::WindowModal);
progress->setFixedSize(this->width()*0.3,this->height()*0.3);
progress->setVisible(true);
QThread::msleep(50);
progress->setValue(currentProgress * 100 / finish);
if (currentProgress == finish)
qDebug()<<"进度条显示完成"<<__LINE__;
progress->hide();
delete progress;
progress = nullptr;
void AdClient::autoPlayTimeOut()
QList<QString> keyList = qMapPicturePath.keys();
if(index>=qMapPicturePath.count())
index=0;
QImage image=qMapPicturePath.value(keyList.at(index));
qDebug()<<"自动播放:"<<keyList.at(index);
showImage(image);
index++;
void AdClient::GUI_WarningMsg(QString title, QString text, QString buttons, QString defaultButton)
Q_UNUSED(buttons)
Q_UNUSED(defaultButton)
QMessageBox *box=new QMessageBox(QMessageBox::Warning,title,text,QMessageBox::Cancel,this);
QTimer::singleShot(5000,this,[=](){
if(!box->isHidden()&&box->isVisible())
box->accept();
});
box->exec();
return;
void AdClient::connectToServer()
if(serverIP->text().isEmpty()||serverPort->text().isEmpty())
QMessageBox::warning(this,"提示","请输入IP或Port");
return;
socket->id=GetLocalIP();
socket->address=serverIP->text();
qDebug()<<"服务器IP:"<<socket->address;
socket->port=serverPort->text().toInt();
qDebug()<<"服务器Port:"<<socket->port;
qDebug()<<"是否已经连接:"<<socket->isValid();
if(socket->isValid())
socket->disconnectFromHost();
socket->connectToHost(QHostAddress(socket->address), socket->port);
qDebug()<<"是否已经连接:"<<socket->isValid();
addate.h 时间处理
#ifndef ADDATE_H
#define ADDATE_H
#include <QTime>
#include <QDate>
#include <QLabel>
#include <QTimer>
class AdDate : public QObject
Q_OBJECT
public:
AdDate(QLabel *_mlabel, QObject *parent = 0);
~AdDate();
void start();
public slots:
void updateTime();
private:
QLabel *mlabel;
QTimer *mtimer;
#endif
addate.cpp 时间处理
#include "addate.h"
AdDate::AdDate(QLabel *_mlabel, QObject *parent):
QObject(parent)
mlabel = _mlabel;
mtimer = new QTimer;
connect(mtimer, SIGNAL(timeout()), this, SLOT(updateTime()));
AdDate::~AdDate()
delete mtimer;
void AdDate::start()
mtimer->start(1000);
void AdDate::updateTime()
QString time = QTime::currentTime().toString("hh:mm:ss")+"\n"
+QDate::currentDate().toString("yy/MM/dd ddd");
mlabel->setText(time);
adsocket.h 客户端Socket处理
#ifndef ADSOCKET_H
#define ADSOCKET_H
#include <QTcpSocket>
#include <QHostAddress>
#include <QAbstractSocket>
#include <QAbstractSocket>
#include <QImage>
#include <QLabel>
#include <QBuffer>
#include <QTime>
#include "string.h"
#include "tcp_MSG.h"
class AdSocket : public QTcpSocket
Q_OBJECT
public:
explicit AdSocket(QObject *parent = 0);
~AdSocket();
QString id;
QString address;
int port;
int readMsgType;
signals:
void sig_showWeather(QString city,QString area,QString wt);
void sig_showTxt(QString tcp_Txt);
void sig_showImage(QImage tcp_image);
void sig_showProgressBar(int currentProgress, int finish);
void GUI_WarningSignal(QString title,QString text,QString buttons,QString defaultButton);
public slots:
void readMsg();
void conSuc();
void conAgain();
void conAgain(QAbstractSocket::SocketError);
private:
int needFileSize;
int currentReceiveSize;
QByteArray currentReceiveByte;
int milsec;
QString fileName;
#endif
adsocket.cpp 客户端Socket处理
#include "adsocket.h"
#include <QDebug>
extern QMap<QString,QImage> qMapPicturePath;
AdSocket::AdSocket(QObject *parent) :
QTcpSocket(parent)
qRegisterMetaType<tcp_MSG>("tcp_MSG");
id = "0011";
connect(this, SIGNAL(readyRead()),this, SLOT(readMsg()));
connect(this, SIGNAL(connected()),this, SLOT(conSuc()));
connect(this, SIGNAL(disconnected()),this, SLOT(conAgain()));
address="127.0.0.1";
port=8888;
connect(this, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(conAgain(QAbstractSocket::SocketError)));
readMsgType=MsgType::Init;
milsec=0;
AdSocket::~AdSocket()
void AdSocket::readMsg()
QByteArray buffer = readAll();
qDebug()<<"进来了"<<__LINE__;
if(readMsgType==MsgType::Init)
tcp_MSG *msg=(tcp_MSG *)buffer.data();
qDebug()<<"进来了"<<__LINE__;
qDebug()<<"类型"<<msg->type;
switch (msg->type)
case WEATHER://天气
QString city=msg->city;
QString area=msg->area;
QString weather=msg->weather;
emit sig_showWeather(city,area,weather);
break;
case MASSEGE:// 留言
QString tcp_Txt=msg->txt;
qDebug()<<"文字信息:"<<tcp_Txt;
emit sig_showTxt(tcp_Txt);
break;
case VIDEO:// 视频
qDebug()<<"发送视频信息:";
break;
case AD_add://添加广告
qDebug()<<"添加广告"<<__LINE__;
qDebug()<<"文件名"<< QString(msg->fileName);
qDebug()<<"编号"<< msg->index;
qDebug()<<"总数"<< msg->allAd_Num;
needFileSize=msg->fileSize;
currentReceiveSize=0;
currentReceiveByte.clear();
QByteArray sendTcpData;
sendTcpData.resize(sizeof(tcp_backMSG));
tcp_backMSG backMsg={
strcpy(backMsg.id,id.toUtf8().data());
backMsg.state=1;
backMsg.type=MsgType::Write_back;
memcpy(sendTcpData.data(),&backMsg,sizeof(tcp_backMSG));
this->write(sendTcpData);
fileName.clear();
fileName=QString(msg->fileName);
readMsgType=MsgType::AD_add;
break;
case AD_delete://删除广告
qDebug()<<"删除广告"<<__LINE__;
qDebug()<<"文件名"<< QString(msg->fileName);
int success= qMapPicturePath.remove(QString(msg->fileName));
if(success)
if(qMapPicturePath.count()>=1)
emit sig_showImage(qMapPicturePath.first());
QImage image(100, 100, QImage::Format_RGBA8888);
image.fill(QColor(0, 0, 0, 0));
emit sig_showImage(image);
emit GUI_WarningSignal("提示","删除广告成功",NULL,NULL);
emit GUI_WarningSignal("提示","删除广告失败",NULL,NULL);
break;
default:
qDebug()<<"";
break;
else if(readMsgType==MsgType::AD_add)
qDebug()<<"添加广告"<<__LINE__;
qDebug()<<"需要接收大小:"<<needFileSize;
QTime startTime = QTime::currentTime();
currentReceiveSize+=buffer.size();
currentReceiveByte+=buffer;
qDebug()<<"当前接收大小:"<<currentReceiveSize;
emit sig_showProgressBar(currentReceiveSize,needFileSize);
QTime endTime = QTime::currentTime();
milsec += startTime.msecsTo(endTime);
if(needFileSize==currentReceiveSize)
qDebug()<<"图片接收完成";
startTime = QTime::currentTime();
QByteArray Ret_bytearray = QByteArray::fromBase64(currentReceiveByte);
QBuffer buffer(&Ret_bytearray);
buffer.open(QIODevice::WriteOnly);
QPixmap imageresult;
imageresult.loadFromData(Ret_bytearray);
qMapPicturePath.insert(fileName,imageresult.toImage());
emit sig_showImage(imageresult.toImage());
readMsgType=MsgType::Init;
endTime = QTime::currentTime();
milsec += startTime.msecsTo(endTime);
qDebug()<<"接收消耗时间"<<milsec<<"毫秒";
void AdSocket::conSuc()
QByteArray sendTcpData;
sendTcpData.resize(sizeof(tcp_backMSG));
tcp_backMSG msg={
strcpy(msg.id,id.toUtf8().data());
msg.state=0;
msg.type=MsgType::Init;
memcpy(sendTcpData.data(),&msg,sizeof(tcp_backMSG));
this->write(sendTcpData);
qDebug()<<"connect success";
void AdSocket::conAgain()
qDebug()<<"套接字断开连接时重新连接";
abort();
connectToHost(QHostAddress(address), port);
void AdSocket::conAgain(QAbstractSocket::SocketError error)
qDebug()<<"连接失败:"<<error;
readMsgType=MsgType::Init;
abort();
if(error==QAbstractSocket::ConnectionRefusedError)
connectToHost(QHostAddress(address), port);
weather.h 天气信息处理
#ifndef WEATHER_H
#define WEATHER_H
#include <QObject>
#include <QLabel>
#include <QDebug>
class Weather : public QObject
Q_OBJECT
public:
explicit Weather( QLabel *_label,QObject *parent = 0);
signals:
public slots:
void showWeather(QString city,QString area,QString weather);
private:
QLabel *label;
QString _city;
QString _area;
#endif
weather.cpp 天气信息处理
#include "weather.h"
Weather::Weather( QLabel *_label, QObject *parent) :
QObject(parent)
label = _label;
void Weather::showWeather(QString city,QString area,QString weather)
_city=city;
qDebug()<<"城市:"<<_city;
_area=area;
qDebug()<<"地区:"<<_area;
weather="\t\t"+_city+"\t"+_area+"\n\t"+weather;
label->setText(weather);
rollmassege.h 滚动信息处理
#ifndef ROLLMASSEGE_H
#define ROLLMASSEGE_H
#include <QLabel>
#include <QEvent>
#include <QTimer>
#include <QRect>
#include <QPainter>
#include <QFont>
class RollMassege : public QLabel
Q_OBJECT
public:
explicit RollMassege(QWidget *parent = 0);
explicit RollMassege(QLabel *_label, QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
signals:
public slots:
void updateMsg();
void showTxt(QString tcp_Txt);
private:
QString txt;
QRect rect;
int offset;
QTimer *timer;
#endif
rollmassege.cpp 滚动信息处理
#include "rollmassege.h"
#include <QDebug>
RollMassege::RollMassege(QWidget *parent) :
QLabel(parent)
RollMassege::RollMassege(QLabel *_label, QWidget *parent) :
QLabel(parent)
rect = _label->geometry();
rect.setWidth(798);
rect.setHeight(80);
setGeometry(rect);
show();
qDebug()<<rect.width()<<" "<<rect.height();
offset = rect.width();
txt = "暂无信息";
timer = new QTimer;
connect(timer, SIGNAL(timeout()), this, SLOT(updateMsg()));
timer->start(50);
void RollMassege::paintEvent(QPaintEvent *event)
Q_UNUSED(event);
QPainter painter(this);
QFont font;
font.setPointSize(16);
painter.setFont(font);
painter.drawText(rect.x()+offset, rect.y()+30, txt);
void RollMassege::updateMsg()
offset--;
if(offset<0) offset = rect.width();
update();
void RollMassege::showTxt(QString tcp_Txt)
txt =tcp_Txt;
update();
Gitee:08Qt-Advertising-Machine Qt广告机
QTcpSocket发送和接收使用 自定义 信息结构体,
结构体需要1字节对齐 ,参考Qt 利用TCP/IP socket通信 发送与接收结构体(简单通信协议解析)
发送
```cpp
QByteArray sendTcpData;
//使用字节数组,将结构体转为字符数组,发送的是字符数组(数据在传输过程中都是byte类型的)
//直接sizeof(senddata)内存会变小,设置了对齐方式解决
sendTcpData.resize(sizeof(tcp_MSG));
//将封装好的结构体转为QByteArray数组,因为传输都是Byte类型
memcpy(sendTcpData.data(),&msg,sizeof(tcp_MSG));
socket->write(sendTcpData);
```cpp
//读取缓冲区数据
QByteArray buffer = readAll();
tcp_MSG *msg=(tcp_MSG *)buffer.data(); //强转为结构体,需要用结构体指针接收
QTcpSocket 的默认缓存区大小是 64KB(65536字节)
图片一般比较大,需要循环接收,校验发送长度和接收长度
因为QTcpSocket是一个基于字节流的套接字,它只能传输二进制数据。而图片文件是一种二进制文件,不能直接传输。因此,需要将图片文件转换为一种可传输的文本格式,如Base64编码。
Base64编码是一种将二进制数据转换为ASCII字符的编码方式。它将每3个字节转换为4个字符,因此可以将任何二进制数据转换为一种文本格式,方便传输
本项目发送图片,使用 先
服务器下发消息类型,客户端回复并开启图片接收; 服务器 再
把图片发给 回复的客户端;
发送
```cpp
*在adtcp.cpp的Ad_SendAction()中先下发消息类型
{
QFileInfo file(path);
QImage image(path);
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
//获取文件的后缀名,并将其转换为大写字母
image.save(&buffer,file.suffix().toUpper().toStdString().c_str()); //将图片保存为PNG/JPG等格式
sendImage = byteArray.toBase64();
msg.fileSize=sendImage.size();
buffer.close();
}
在adtcp.cpp的read_back()中先下发消息类型
{
// 返回此信号的 发送对象
QTcpSocket getSocket=qobject_cast(sender());
//读取缓冲区数据
QByteArray buffer = getSocket->readAll();//client_list->last()->msocket->readAll();// 读取最后客户端(也就是最新的)
tcp_backMSG msg=(tcp_backMSG )buffer.data(); //强转为结构体,需要用结构体指针接收
else if(msg->type==MsgType::Write_back&&msg->state==1)
getSocket->write(sendImage);
// 用于等待发送的数据被写入到网络套接字描述符中,这样就可以确保数据完全被发送出去,
//该函数会阻塞程序继续执行,直到数据被完全发送出去
if (getSocket->waitForBytesWritten())
getSocket->flush(); //释放socket缓存
```cpp
* 在adsocket.cpp的readMsg()先回复并开启图片接收
//读取缓冲区数据
QByteArray buffer = readAll();
tcp_MSG *msg=(tcp_MSG *)buffer.data(); //强转为结构体,需要用结构体指针接收
needFileSize=msg->fileSize;// 需要接收图片大小
QByteArray sendTcpData;
//使用字节数组,将结构体转为字符数组,发送的是字符数组(数据在传输过程中都是byte类型的)
//直接sizeof(senddata)内存会变小,设置了对齐方式解决
sendTcpData.resize(sizeof(tcp_backMSG));
tcp_backMSG backMsg={};
strcpy(backMsg.id,id.toUtf8().data());
backMsg.state=1;
backMsg.type=MsgType::Write_back;
//将封装好的结构体转为QByteArray数组,因为传输都是Byte类型
memcpy(sendTcpData.data(),&backMsg,sizeof(tcp_backMSG));
this->write(sendTcpData);// 回复
* 在adsocket.cpp的readMsg()图片接收
QByteArray buffer = readAll();
qDebug()<<"需要接收大小:"<<needFileSize;
currentReceiveSize+=buffer.size();
currentReceiveByte+=buffer;//当前累计接收大小
if(needFileSize==currentReceiveSize)
{qDebug()<<"图片接收完成";
QByteArray Ret_bytearray = QByteArray::fromBase64(currentReceiveByte);
QBuffer buffer(&Ret_bytearray);
buffer.open(QIODevice::WriteOnly);
QPixmap imageresult;
imageresult.loadFromData(Ret_bytearray);
QImage pic=imageresult.toImage();
下载地址:
国内下载 http://47.98.241.45/outbound/Public/sip/eyeBeam.zip(eyebeam)
国内下载 sipphone.cc/phone_lite_…
国外下载 phone.ddrj.com/phone_lite_…
百度云下载 pan.baidu.com/s/1hs64Nbu
双击 phone.exe AI源码,VOS,SIP软件
AI_WX_3307623172