windows获取进程流量
来源:互联网 发布:中国家暴数据统计图 编辑:程序博客网 时间:2024/04/28 10:00
铺垫
获取进程使用的端口
http://blog.csdn.net/rongxiaojun1989/article/details/42417767
抓包
http://blog.csdn.net/rongxiaojun1989/article/details/42744761
IP数据包格式
http://blog.csdn.net/rongxiaojun1989/article/details/42743503
概要方案
1. 获取进程此刻使用的端口号
2. 网卡抓包
3. 流量累积
4. 计算结果
详细方案
1. 获取进程此刻使用的端口号
2. 在各个网卡抓包
3. 拆包解析,查看四元组
4. 流量累计
5. 流量累计结果与所用时间的比值即为结果
附加知识
经验证,非阻塞recv抓包30w约等于1s,视电脑处理速度而定。
实现代码
bool GetProcNetworkFlow(const std::string &sNameProc, double &dbpsRecv, double &dbpsSend){/*获取进程Port*/std::set<DWORD> setPort;if(!GetProcessPort(sNameProc, setPort)){printf("GetProcessPort == false, sNameProc=%s\n", sNameProc.c_str());return false;}/*获取所有网卡IP*/std::vector<std::string> vecHostIp;if(!GetLocalHostIp(vecHostIp)){printf("GetLocalHostIp == false\n");return false;}/*遍历网卡*/for(size_t i = 0; i != vecHostIp.size(); ++i){/*创建RAW socket*/SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);if(INVALID_SOCKET == s){printf("socket == INVALID_SOCKET, ErrorCode=%d\n", GetLastError());return false;}/*设置非阻塞*/DWORD dwCmdParam = 1;if(SOCKET_ERROR == ioctlsocket(s, FIONBIO, &dwCmdParam)){printf("ioctlsocket(s, FIONBIO, &dwCmdParam) == SOCKET_ERROR, ErrorCode=%d\n", GetLastError());return false;}/*初始化sockaddr*/sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(vecHostIp[i].c_str());addr.sin_port = htons(4444);/*绑定网卡地址*/if(SOCKET_ERROR == bind(s, (sockaddr*)&addr, sizeof(addr))){printf("bind == SOCKET_ERROR, ErrorCode=%d\n", GetLastError());return 0;}/*设置socket模式*/RCVALL_VALUE emRcvallValue = RCVALL_IPLEVEL;DWORD dwBytesReturned = 0;if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL)){printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d\n", GetLastError());return false;}/*设置计时器*/LARGE_INTEGER liTimeStart, liTimeEnd, liTimeElapse;LARGE_INTEGER liFrequency;QueryPerformanceFrequency(&liFrequency);QueryPerformanceCounter(&liTimeStart);/*抓包*/int iBytesRecv = 0, iBytesSend = 0;char cBuffer[100*1024] = {0};for(int k = 0; k != 300000; ++k){int iLenRecv = recv(s, cBuffer, 100*1024, 0);if(SOCKET_ERROR == iLenRecv){if(WSAEWOULDBLOCK == GetLastError())continue;printf("recv == SOCKET_ERROR, ErrorCode=%d\n", GetLastError());break;}if(0 == iLenRecv){printf("recv == SOCKET_ERROR, Connection Closed\n");break;}cBuffer[iLenRecv] = '\0';/*验证IP协议版本*/int iVersionIp = static_cast<unsigned char>(cBuffer[0]) >> 4;if(iVersionIp != 4)continue;/*验证协议*/int iProto = static_cast<unsigned char>(cBuffer[9]);if(iProto != 6 && iProto != 17)continue;/*取IP头长度*/int iLenIpHeader = cBuffer[0] & 0x0F;iLenIpHeader *= 4;/*获取Ip*/std::string sIpSrc, sIpDest;for(int m = 0; m != 4; ++m){sIpSrc += std::to_string(static_cast<ULONGLONG>(static_cast<unsigned char>(cBuffer[12+m])));sIpDest += std::to_string(static_cast<ULONGLONG>(static_cast<unsigned char>(cBuffer[16+m])));if(m != 3){sIpSrc += ".";sIpDest += ".";}}/*判断传输方向*/bool bRecv;if(std::find(vecHostIp.begin(), vecHostIp.end(), sIpDest) != vecHostIp.end())bRecv = true;else if(std::find(vecHostIp.begin(), vecHostIp.end(), sIpSrc) != vecHostIp.end())bRecv = false;elsecontinue;/*获取Port*/int iPortSrc = 0, iPortDest = 0;memcpy(&iPortSrc, &cBuffer[iLenIpHeader], 2);memcpy(&iPortDest, &cBuffer[iLenIpHeader+2], 2);iPortSrc = ntohs(iPortSrc);iPortDest = ntohs(iPortDest);/*获取本地端口*/int iPortLocal = 0;if(bRecv)iPortLocal = iPortDest;elseiPortLocal = iPortSrc;/*验证Port*/if(setPort.find(iPortLocal) == setPort.end())continue;/*获取IP总长*/int iLenIp = 0;memcpy(&iLenIp, &cBuffer[2], 2);iLenIp = ntohs(iLenIp);/*取实际数据长*/int iLenData = 0;if(iProto == 6){int iLenTcpHeader = static_cast<unsigned char>(cBuffer[iLenIpHeader+12]) >> 4;iLenTcpHeader *= 4;iLenData = iLenIp - iLenIpHeader - iLenTcpHeader;}else{iLenData = iLenIp - iLenIpHeader - 20;}/*流量累加*/if(bRecv)iBytesRecv += iLenData;elseiBytesSend += iLenData;}/*计算时间间隔*/QueryPerformanceCounter(&liTimeEnd);liTimeElapse.QuadPart = liTimeEnd.QuadPart - liTimeStart.QuadPart;double dTimeElapse = static_cast<double>(liTimeElapse.QuadPart) / liFrequency.QuadPart;/*统计流量*/dbpsRecv += static_cast<double>(iBytesRecv) * 8 / dTimeElapse;dbpsSend += static_cast<double>(iBytesSend) * 8 / dTimeElapse;/*关闭SIO_RCVALL*/emRcvallValue = RCVALL_OFF;if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL)){printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d\n", GetLastError());return false;}/*关闭socket*/closesocket(s);}return true;}
0 0
- windows获取进程流量
- 获取进程流量信息
- windows获取流量
- windows编程->进程获取
- windows获取进程端口
- windows xp 获取进程号
- Windows获取进程的方法
- Windows 获取父进程ID
- windows 命令行获取进程参数
- windows获取pid进程路径
- 获取Windows进程的父进程编号
- 今天看了一下 windows 如何获取流量的接口
- Windows进程监控工具(1)--Windows下进程获取
- 进程流量显示
- 获取Windows系统的进程运行信息
- 获取Windows系统的进程运行信息
- 获取Windows系统的进程运行信息
- Windows 驱动:获取当前进程名
- week10-实现网站的登录、注册功能
- Elixir Tuple常用的几个方法
- android下载
- poj3268 Silver Cow Party(最短路变形)
- [Java Web]动态生成静态页
- windows获取进程流量
- express书写URL时候被刨的坑
- JavaScript入门篇之正则表达式
- FFMPEG获取视频播放时长
- 【块状树】
- oracle 下的schema
- Flask Web Development —— 基本应用程序结构(下)
- Flask Web Development——安装
- dwz 页面上关闭dialog弹出层,navTab 界面方式。