438 lines
11 KiB
C++
438 lines
11 KiB
C++
#include "filetranseceiver.h"
|
|
#include <QDebug>
|
|
#include <QFile>
|
|
#include <QString>
|
|
#include <QTimer>
|
|
#include <iostream>
|
|
#include <string>
|
|
//#include "LogInfo.h"
|
|
#include <QCoreApplication>
|
|
|
|
FileTranseceiver::FileTranseceiver(uint16_t hostshort)
|
|
{
|
|
// struct sockaddr_in server_addr;
|
|
// bzero(&server_addr, sizeof(server_addr)); // 置字节字符串前n个字节为0,包括'\0'
|
|
// server_addr.sin_family = AF_INET;
|
|
// server_addr.sin_addr.s_addr = htons(INADDR_ANY); // 转小端,INADDR_ANY就是指定地址为0.0.0.0的地址
|
|
// server_addr.sin_port = htons(5000);
|
|
serverThead = NULL;
|
|
sockfd = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
port=hostshort;
|
|
struct sockaddr_in seraddr;
|
|
seraddr.sin_family = AF_INET;
|
|
seraddr.sin_port = htons(hostshort);
|
|
seraddr.sin_addr.s_addr = htons(INADDR_ANY);
|
|
int tmp = 1;
|
|
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(int));
|
|
if(bind(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr)) == -1)
|
|
{
|
|
qDebug() << "tftp server bind error";
|
|
return;
|
|
}
|
|
|
|
if(listen(sockfd,5) == -1)
|
|
{
|
|
qDebug() << "listen error";
|
|
return;
|
|
}
|
|
|
|
serverThead = new QThread();
|
|
moveToThread(serverThead);
|
|
QObject::connect(serverThead, SIGNAL(started()), this, SLOT(connectListen()));
|
|
//connect(&m_thread, SIGNAL(finished()), this, SLOT(deleteLater()));
|
|
// serverThead->start();
|
|
// qDebug()<<"tftp server on...";
|
|
if(hostshort==5002)
|
|
{
|
|
refresh_timer = new QTimer();
|
|
connect(refresh_timer, SIGNAL(timeout()), this, SLOT(refreshtimerHandler()),Qt::DirectConnection);
|
|
}
|
|
}
|
|
FileTranseceiver::~FileTranseceiver(void)
|
|
{
|
|
if(serverThead) {
|
|
disconnect(serverThead, SIGNAL(started()), this, SLOT(connectListen()));
|
|
if (serverThead->isRunning()) {
|
|
serverThead->quit();
|
|
serverThead->wait();
|
|
}
|
|
}
|
|
if(connfd)
|
|
close(connfd);
|
|
if(sockfd)
|
|
close(sockfd);
|
|
}
|
|
void FileTranseceiver::start()
|
|
{
|
|
if(serverThead)
|
|
{
|
|
serverThead->start();
|
|
}
|
|
qDebug()<<"tftp server on...";
|
|
}
|
|
|
|
void FileTranseceiver::connectListen()
|
|
{
|
|
switch(port)
|
|
{
|
|
case 5001:
|
|
connectListen5001();
|
|
break;
|
|
case 5002:
|
|
connectListen5002();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void FileTranseceiver::connectListen5001()
|
|
{
|
|
|
|
struct msg info;
|
|
struct sockaddr_in cliaddr;
|
|
int len = sizeof(cliaddr);
|
|
pid_t pid;
|
|
int n;
|
|
QString fileName;
|
|
do
|
|
{
|
|
connfd = accept(sockfd,(struct sockaddr *)&cliaddr,(socklen_t *)&len);
|
|
if(connfd == -1)
|
|
{
|
|
qDebug() << "accept";
|
|
continue;
|
|
}
|
|
|
|
{
|
|
//close(sockfd);
|
|
while(1)
|
|
{
|
|
n = recv(connfd,&info,sizeof(info),0);
|
|
if(n == -1)
|
|
{
|
|
qDebug() << "recv";
|
|
//exit(EXIT_FAILURE);
|
|
break;
|
|
}
|
|
if(n == 0)
|
|
{
|
|
qDebug() << "客户端退出";
|
|
break;
|
|
}
|
|
switch(info.type)
|
|
{
|
|
case DOWN:
|
|
ftp_download(connfd,info);
|
|
break;
|
|
case UP:
|
|
upload_ftp(connfd,info);
|
|
fileName = QString(info.fname);
|
|
qDebug()<<"emit fileRecieved(fileName)";
|
|
emit fileRecieved(fileName);
|
|
break;
|
|
case UPGRADE:
|
|
upload_and_upgrade(connfd,info);
|
|
QFile::remove("/home/plg/QtUI");
|
|
if(!QFile::copy("/tmp/QtUI", "/home/plg/QtUI"))
|
|
{
|
|
QMessageBox::about(0, tr("错误"), tr("更新失败!"));
|
|
break;
|
|
}
|
|
QMessageBox::information(0, tr("提示"), tr("软件更新成功,重启后生效!"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
close(connfd);
|
|
}
|
|
}
|
|
while(1);
|
|
}
|
|
|
|
//将某文件中的内容传给客户端
|
|
int FileTranseceiver::ftp_download(int connfd,struct msg info)
|
|
{
|
|
FILE *fp;
|
|
|
|
char name[100];
|
|
memset(name,0,100);
|
|
sprintf(name, DOC_DIR"/%s",info.fname);
|
|
fp = fopen(name,"r");
|
|
if(fp == NULL)
|
|
{
|
|
info.flag = FAIL;
|
|
send(connfd,&info,sizeof(info),0);
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
info.flag = SUCCESS;
|
|
send(connfd,&info,sizeof(info),0);
|
|
}
|
|
|
|
unsigned int len;
|
|
while(1)
|
|
{
|
|
len = fread(info.buf,1,sizeof(info.buf),fp);
|
|
send(connfd,info.buf,len,0);
|
|
|
|
if(len < sizeof(info.buf) && feof(fp) != 0)
|
|
break;
|
|
}
|
|
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
//接收客户端上传的文件内容
|
|
int FileTranseceiver::upload_ftp(int connfd,struct msg info)
|
|
{
|
|
FILE *fp;
|
|
char name[100];
|
|
sprintf(name, "/tmp/%s",info.fname);
|
|
fp = fopen(name,"w");
|
|
if(fp == NULL)
|
|
{
|
|
info.flag = FAIL;
|
|
send(connfd,&info,sizeof(info),0);
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
info.flag = SUCCESS;
|
|
send(connfd,&info,sizeof(info),0);
|
|
}
|
|
unsigned int len;
|
|
while(1)
|
|
{
|
|
len = recv(connfd,info.buf,sizeof(info.buf),0);
|
|
fwrite(info.buf,1,len,fp);
|
|
if(len < sizeof(info.buf))
|
|
break;
|
|
}
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
int FileTranseceiver::upload_and_upgrade(int connfd,struct msg info)
|
|
{
|
|
FILE *fp;
|
|
char name[100];
|
|
sprintf(name, "/tmp/%s",info.fname);
|
|
fp = fopen(name,"wb");
|
|
unsigned int len;
|
|
while(1)
|
|
{
|
|
len = recv(connfd,info.buf,sizeof(info.buf),0);
|
|
if(0<len)
|
|
fwrite(info.buf,1,len,fp);
|
|
else break;
|
|
}
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
QByteArray FileTranseceiver::read(int length)
|
|
{
|
|
char buf[100];
|
|
QByteArray b;
|
|
//recv file contant
|
|
unsigned int len;
|
|
while(1)
|
|
{
|
|
len = recv(connfd,buf,length-b.size(),0);
|
|
|
|
if(len ==0)
|
|
{
|
|
qDebug()<<"Connection Closed";
|
|
break;
|
|
}
|
|
b.append(buf,len);
|
|
|
|
if(b.size()==length)break;
|
|
}
|
|
return b;
|
|
}
|
|
/*
|
|
void MySleep100(unsigned int msec)
|
|
{
|
|
|
|
QTime dieTime = QTime::currentTime().addMSecs(msec);
|
|
|
|
while( QTime::currentTime() < dieTime )
|
|
|
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
|
|
|
}
|
|
*/
|
|
static bool flagOfSockfdClosed = true;
|
|
void FileTranseceiver::connectListen5002()
|
|
{
|
|
struct sockaddr_in cliaddr;
|
|
int len = sizeof(cliaddr);
|
|
do
|
|
{
|
|
connfd = accept(sockfd,(struct sockaddr *)&cliaddr,(socklen_t *)&len);
|
|
if(connfd == -1)
|
|
{
|
|
qDebug() << "5002 Connection failure :"<<connfd;
|
|
continue;
|
|
}
|
|
flagOfSockfdClosed = false;
|
|
refresh_timer->start(5000);
|
|
{
|
|
while(1)
|
|
{
|
|
if(flagOfSockfdClosed)
|
|
break;
|
|
QByteArray a=read(7);
|
|
showData("read-a=",a);
|
|
if(!a.startsWith(QByteArray::fromHex("5aa5")))
|
|
{
|
|
qDebug() << "无效数据-Header";
|
|
break;
|
|
}
|
|
|
|
int InstructionCode=a.mid(2,1).toHex().toInt(0,16);
|
|
int DataLenght=a.mid(3,4).toHex().toInt(0,16);
|
|
|
|
if(DataLenght >60)
|
|
{
|
|
qDebug() << "无效数据-DataLenght";
|
|
break;
|
|
}
|
|
|
|
QByteArray b=read(DataLenght+3);
|
|
showData("read-b=",b);
|
|
if(!b.endsWith(QByteArray::fromHex("a55a")))
|
|
{
|
|
qDebug() << "无效数据-Ender";
|
|
break;
|
|
}
|
|
if(CheckSumIn(a+b))
|
|
{
|
|
switch (InstructionCode) {
|
|
case 0x01:InstructionCode1(a+b); break;//启动指令
|
|
case 0x02:InstructionCode2(a+b); break;//停止指令
|
|
case 0x03:InstructionCode3(b.left(DataLenght));break;//喷码指令
|
|
case 0x04:InstructionCode4(a+b);break;//获取缓存指令
|
|
//case 0x05:break;//喷码完成
|
|
//case 0x06:break;//
|
|
case 0x07:InstructionCode7(a+b);break;//清空缓存
|
|
case 0x08:InstructionCode8(a+b);break;//丢弃废膜指令
|
|
default:
|
|
write(InstructionCode,QByteArray::fromHex("00"));
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
write(InstructionCode,QByteArray::fromHex("00"));
|
|
qDebug() << "无效数据-Checksum";
|
|
break;
|
|
}
|
|
}
|
|
if(!flagOfSockfdClosed)
|
|
close(connfd);
|
|
}
|
|
refresh_timer->stop();
|
|
}
|
|
while(1);
|
|
}
|
|
bool FileTranseceiver::CheckSumIn( QByteArray a)
|
|
{
|
|
UCHAR add8=CheckSumIn((UCHAR*)a.data(),a.length()-3);
|
|
// qDebug()<<"CheckSumIn: "<<add8;
|
|
return add8==(UCHAR)a.at(a.length()-3);
|
|
}
|
|
|
|
UCHAR FileTranseceiver::CheckSumIn( UCHAR *buf, unsigned int len)
|
|
{
|
|
unsigned int i;
|
|
UCHAR checksum;
|
|
checksum = 0;
|
|
for (i = 0; i < (len - 0); i++)
|
|
{
|
|
checksum += buf[i];
|
|
}
|
|
return checksum;
|
|
}
|
|
|
|
void FileTranseceiver::showData(QString tag, QByteArray dat)const
|
|
{
|
|
int i,len;
|
|
QString s="";
|
|
len = dat.length();
|
|
for(i=0;i<len;i++)
|
|
{
|
|
s+=QString().sprintf("%02X ",(unsigned char)dat.at(i));
|
|
}
|
|
if(s != "5A A5 06 00 00 00 01 01 07 A5 5A " && s != "5A A5 05 00 00 00 01 01 06 A5 5A ")
|
|
qDebug()<<tag<<s;
|
|
}
|
|
void FileTranseceiver::refreshtimerHandler()
|
|
{
|
|
write(0x06,QByteArray::fromHex("01"));
|
|
}
|
|
void FileTranseceiver::write(int code,QByteArray d)
|
|
{
|
|
mutex.lock();
|
|
QByteArray s=QByteArray::fromHex("5aa5");
|
|
s.append(code);
|
|
s.append(QByteArray::fromHex(QString::number(d.size(),16).rightJustified(8,'0',true).toStdString().data()));
|
|
s.append(d);
|
|
UCHAR add8=CheckSumIn((UCHAR*)s.data(),s.length());
|
|
s.append(add8);
|
|
s.append(QByteArray::fromHex("a55a"));
|
|
QString log=s.toHex();
|
|
showData("write=",s);
|
|
int ret = 0;
|
|
ret == send(connfd,s.data(),s.length(),0);
|
|
if(ret == -1) {
|
|
qDebug()<<"Send Failure";
|
|
close(connfd);
|
|
refresh_timer->stop();
|
|
flagOfSockfdClosed = true;
|
|
}
|
|
mutex.unlock();
|
|
}
|
|
|
|
void FileTranseceiver::InstructionCode1(QByteArray d){
|
|
emit printer_operate_0x01();
|
|
}
|
|
void FileTranseceiver::InstructionCode2(QByteArray d){
|
|
emit printer_operate_0x02();
|
|
write(2,QByteArray::fromHex("01"));
|
|
}
|
|
void FileTranseceiver::InstructionCode3(QByteArray d)
|
|
{
|
|
emit printer_operate_0x03(QString::fromUtf8(d));
|
|
write(3,QByteArray::fromHex("01"));
|
|
}
|
|
void FileTranseceiver::InstructionCode4(QByteArray d){
|
|
emit printer_operate_0x04();
|
|
}
|
|
void FileTranseceiver::InstructionCode5(QByteArray d){
|
|
write(5,QByteArray::fromHex("01"));
|
|
}
|
|
void FileTranseceiver::InstructionCode6(QByteArray d){}
|
|
|
|
void FileTranseceiver::InstructionCode7(QByteArray d){
|
|
emit clear_DataCache();
|
|
write(7,QByteArray::fromHex("01"));
|
|
}
|
|
|
|
void FileTranseceiver::InstructionCode8(QByteArray d){
|
|
emit drop_NextSignal();
|
|
write(8,QByteArray::fromHex("01"));
|
|
}
|
|
|
|
//启动指令-回收槽就绪
|
|
void FileTranseceiver::printer_operate_0x01_result(int status)
|
|
{
|
|
write(1,QByteArray::fromHex(status==0?"00":"01"));
|
|
}
|
|
void FileTranseceiver::WriteInstructionCodeAck(int InstructionCode,QByteArray data)
|
|
{
|
|
write(InstructionCode,data);
|
|
}
|