Qt窗口获取Tftpd32_svc服务下载信息
前言
一个由Qt开发的Windows小工具需要布置Tftp协议服务端来支持设备下载数据,并显示下载列表(进度、下载源等)。
考虑开发方便,优先使用了Qtftp方案,经测试发现,不够稳定,会有下载超时的情况,故重新选择使用Tftpd64方案。
Tftpd64
地址
官网地址
安装包地址
源码地址
问题描述
源码未提供Tftpd二次开发api,无法直接使用Tftpd64获取下载进度等信息。
阅读源码分析如下:
- 将Tftp协议移植出来工作量太大,暂否决
- tftpd32 service edition 服务与UI分离,进程间通讯采用TCP协议,尝试使用此方案
Qt窗口代码实现
if (!initConnect())
{
qCritical("initConnect fail");
return;
}
Sleep(100);
char path[] = "D:\\Work\\resource";
sendMsg(C_TFTP_CHG_WORKING_DIR, path, strlen(path)+1);
//sendMsg(C_RRQ_WORKING_DIR, "", 1);
m_isRun = true;
while (m_isRun)
{
struct S_ConsoleMsg sMsg;
if (!tcpPPRecv((char*)&sMsg, sizeof(sMsg)))
{
qWarning("");
continue;
}
switch (sMsg.type)
{
case C_ERROR:
qInfo("C_ERROR");
break;
case C_WARNING:
qInfo("C_WARNING");
break;
case C_TFTP_TRF_NEW:
{
const S_TftpTrfNew& newTrf = sMsg.u.trf_new;
qInfo("---------C_TFTP_TRF_NEW-----------");
char addr[16] = { 0 };
getnameinfo((LPSOCKADDR)&newTrf.from_addr, sizeof(newTrf.from_addr),
addr, sizeof addr,
NULL, 0,
NI_NUMERICHOST);
qInfo("addr: %s", addr);
qInfo("dwTransferId: %d", newTrf.dwTransferId);
qInfo("szFile: %s", newTrf.szFile);
qInfo("dwTransfert: %d", newTrf.stat.dwTransfert);
qInfo("dwTotalBytes: %d", newTrf.stat.dwTotalBytes);
qInfo("dwTotalTimeOut: %d", newTrf.stat.dwTotalTimeOut);
qInfo("dwTransferSize: %d", newTrf.stat.dwTransferSize);
qInfo("StartTime: %d", newTrf.stat.StartTime);
qInfo("dLastUpdate: %d", newTrf.stat.dLastUpdate);
qInfo("ret_code: %d", newTrf.stat.ret_code);
emit AppEvent::Instance()->sig_tftpNew(newTrf.dwTransferId, addr, newTrf.szFile);
break;
}
case C_TFTP_TRF_END:
{
const S_TftpTrfEnd& endTrf = sMsg.u.trf_end;
qInfo("---------C_TFTP_TRF_END-----------");
qInfo("dwTransferId: %d", endTrf.dwTransferId);
qInfo("dwTransfert: %d", endTrf.stat.dwTransfert);
qInfo("dwTotalBytes: %d", endTrf.stat.dwTotalBytes);
qInfo("dwTotalTimeOut: %d", endTrf.stat.dwTotalTimeOut);
qInfo("dwTransferSize: %d", endTrf.stat.dwTransferSize);
qInfo("StartTime: %d", endTrf.stat.StartTime);
qInfo("dLastUpdate: %d", endTrf.stat.dLastUpdate);
qInfo("ret_code: %d", endTrf.stat.ret_code);
emit AppEvent::Instance()->sig_tftpEnd(endTrf.dwTransferId);
break;
}
case C_TFTP_TRF_STAT:
{
qInfo("---------C_TFTP_TRF_STAT-----------");
const S_TftpTrfStat& statTrf = sMsg.u.trf_stat;
for (int i = 0; i < statTrf.nbTrf; i++)
{
qInfo("dwTransferId: %d", statTrf.t[i].dwTransferId);
qInfo("dwTransfert: %d", statTrf.t[i].stat.dwTransfert);
qInfo("dwTotalBytes: %d", statTrf.t[i].stat.dwTotalBytes);
qInfo("dwTotalTimeOut: %d", statTrf.t[i].stat.dwTotalTimeOut);
qInfo("dwTransferSize: %d", statTrf.t[i].stat.dwTransferSize);
qInfo("StartTime: %d", statTrf.t[i].stat.StartTime);
qInfo("dLastUpdate: %d", statTrf.t[i].stat.dLastUpdate);
qInfo("ret_code: %d", statTrf.t[i].stat.ret_code);
emit AppEvent::Instance()->sig_tftpProgress(statTrf.t[i].dwTransferId,
statTrf.t[i].stat.dwTotalBytes*100/ statTrf.t[i].stat.dwTransferSize);
}
break;
}
default:
qInfo("__-------------%d----------", sMsg.type);
break;
}
}
效果图
demo下载地址
下载地址