#include "filetranseceiver.h" #include #include #include #include #include #include //#include "LogInfo.h" #include 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(0start(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: "<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); }