Qt窗口获取Tftpd32_svc服务下载信息

发布于:2025-02-11 ⋅ 阅读:(45) ⋅ 点赞:(0)

前言

一个由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下载地址

下载地址

在此记录只为交流学习,未有其它意图


网站公告

今日签到

点亮在社区的每一天
去签到