在Windows XP中,可以通过设置"连接时在通知区域显示图标"来让系统托盘显示一个闪烁的图标,以指示网络流量。然而,在Windows 7中,只能看到一个静态图标,而没有动画来显示流量。为了满足包括在内的那些希望看到数据包进出网络的用户,决定创建一个简单的应用程序。
很久以前,开发了一个名为Network Lights的小工具,它可以在网络接口上闪烁键盘LED(发光二极管),以指示进出网络包。这个工具及其源代码可以在这里找到:。将其修改为控制系统托盘图标,而不是键盘LED,并适应了Windows 7环境。
这个程序的核心是一个单独的线程,它获取当前的TCP、UDP和ICMP统计数据,并决定在系统托盘上显示哪个图标:
void TCPThread(LPVOID pInfo) {
MIB_TCPSTATS mibTcpStats;
MIB_UDPSTATS mibUdpStats;
MIB_ICMP mibIcmpStats;
UINT nCounter = 0;
DWORD dwSegTcpRcvd = 0;
DWORD dwSegTcpSent = 0;
DWORD dwSegUdpRcvd = 0;
DWORD dwSegUdpSent = 0;
DWORD dwSegIcmpRcvd = 0;
DWORD dwSegIcmpSent = 0;
DWORD dwLocalOutSegs = 0;
DWORD dwLocalInSegs = 0;
while (m_bWorkContinue) {
if (m_bSetIconContinue) {
m_dwPacketsSent = 0;
m_dwPacketsReceived = 0;
m_bSetIconContinue = FALSE;
if (m_bDisplayTCP) {
if (GetTcpStatistics(&mibTcpStats) == NO_ERROR) {
dwLocalInSegs = mibTcpStats.dwInSegs;
dwLocalOutSegs = mibTcpStats.dwOutSegs;
m_dwPacketsSent += dwLocalOutSegs;
m_dwPacketsReceived += dwLocalInSegs;
if (dwLocalOutSegs > dwSegTcpSent && dwLocalInSegs > dwSegTcpRcvd) {
dwSegTcpSent = dwLocalOutSegs;
dwSegTcpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hActiveIcon);
goto done;
} else if (dwLocalOutSegs > dwSegTcpSent && dwLocalInSegs <= dwSegTcpRcvd) {
dwSegTcpSent = dwLocalOutSegs;
SetTrayIcon(NIM_MODIFY, m_hSendIcon);
goto done;
} else if (dwLocalInSegs > dwSegTcpRcvd && dwLocalOutSegs <= dwSegTcpSent) {
dwSegTcpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hReceiveIcon);
goto done;
} else {
nCounter++;
if (nCounter == 10) {
nCounter = 0;
SetTrayIcon(NIM_MODIFY, m_hInactiveIcon);
goto done;
}
}
}
}
if (m_bDisplayUDP) {
if (GetUdpStatistics(&mibUdpStats) == NO_ERROR) {
dwLocalInSegs = mibUdpStats.dwInDatagrams;
dwLocalOutSegs = mibUdpStats.dwOutDatagrams;
m_dwPacketsSent += dwLocalOutSegs;
m_dwPacketsReceived += dwLocalInSegs;
if (dwLocalOutSegs > dwSegUdpSent && dwLocalInSegs > dwSegUdpRcvd) {
dwSegUdpSent = dwLocalOutSegs;
dwSegUdpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hActiveIcon);
goto done;
} else if (dwLocalOutSegs > dwSegUdpSent && dwLocalInSegs <= dwSegUdpRcvd) {
dwSegUdpSent = dwLocalOutSegs;
SetTrayIcon(NIM_MODIFY, m_hSendIcon);
goto done;
} else if (dwLocalInSegs > dwSegUdpRcvd && dwLocalOutSegs <= dwSegUdpSent) {
dwSegUdpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hReceiveIcon);
goto done;
} else {
nCounter++;
if (nCounter == 10) {
nCounter = 0;
SetTrayIcon(NIM_MODIFY, m_hInactiveIcon);
goto done;
}
}
}
}
if (m_bDisplayICMP) {
if (GetIcmpStatistics(&mibIcmpStats) == NO_ERROR) {
dwLocalInSegs = mibIcmpStats.stats.icmpInStats.dwMsgs;
dwLocalOutSegs = mibIcmpStats.stats.icmpOutStats.dwMsgs;
m_dwPacketsSent += dwLocalOutSegs;
m_dwPacketsReceived += dwLocalInSegs;
if (dwLocalOutSegs > dwSegIcmpSent && dwLocalInSegs > dwSegIcmpRcvd) {
dwSegIcmpSent = dwLocalOutSegs;
dwSegIcmpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hActiveIcon);
goto done;
} else if (dwLocalOutSegs > dwSegIcmpSent && dwLocalInSegs <= dwSegIcmpRcvd) {
dwSegIcmpSent = dwLocalOutSegs;
SetTrayIcon(NIM_MODIFY, m_hSendIcon);
goto done;
} else if (dwLocalInSegs > dwSegIcmpRcvd && dwLocalOutSegs <= dwSegIcmpSent) {
dwSegIcmpRcvd = dwLocalInSegs;
SetTrayIcon(NIM_MODIFY, m_hReceiveIcon);
goto done;
} else {
nCounter++;
if (nCounter == 10) {
nCounter = 0;
SetTrayIcon(NIM_MODIFY, m_hInactiveIcon);
goto done;
}
}
}
}
done:
m_bSetIconContinue = TRUE;
}
Sleep(m_nDuration);
}
m_hTcpThread = NULL;
}
与原始的Windows XP工具(每个接口都有单独的指示器)不同,这个程序指示所有可用接口上的进出网络包。