| DWORD       dwOwningPid;//关联的进程ID
 } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;
 
	int GetTcpConnect(){
 HMODULE hMod = LoadLibrary("Iphlpapi.dll");
 if(!hMod)
 {
 AfxMessageBox("加载Iphlpapi.dll出错");
 return 0;
 }
 PFNGetExtendedTcpTable pfnGetTcpTable =
 (PFNGetExtendedTcpTable)::GetProcAddress(hMod,"GetExtendedTcpTable");//获取
 函数地址
 PMIB_TCPTABLE_OWNER_PID pTcpTable = new MIB_TCPTABLE_OWNER_PID;
 DWORD dwSize = sizeof(MIB_TCPTABLE_OWNER_PID);
 if (pfnGetTcpTable(pTcpTable, &dwSize,
 TRUE,AF_INET,TCP_TABLE_OWNER_PID_ALL,0) == ERROR_INSUFFICIENT_BUFFER)
 {//第一次调用时不知道要传入的缓冲区大小,所以要试探一下,参数dwSize会返
 回真正需要的大小
 delete pTcpTable;
 
	   pTcpTable = (MIB_TCPTABLE_OWNER_PID *)new char[dwSize];//重新分配缓冲区
 }
 if(pfnGetTcpTable(pTcpTable,&dwSize,TRUE,AF_INET,TCP_TABLE_OWNER_PID_AL
 L,0) != NO_ERROR)
 {
 AfxMessageBox("获取TCP连接出错");
 delete pTcpTable;
 return 0;
 }
 int nNum = (int) pTcpTable->dwNumEntries; //TCP连接的数目
 for(int i=0;i<nNum;i++)
 {
 printf(“本地地址:%s:%d  远程地址:%s:%d  状态:%d  进程ID:%d”,
 inet_ntoa(*(in_addr*)& pTcpTable->table[i].dwLocalAddr), //本地IP 地址
 htons(pTcpTable->table[i].dwLocalPort), //本地端口
 inet_ntoa(*(in_addr*)& pTcpTable->table[i].dwRemoteAddr), //远程IP地址
 htons(pTcpTable->table[i].dwRemotePort), //远程端口
 
	pTcpTable->table[i].dwState, //状态pTcpTable->table[i].dwOwningPid); //所属进程PID
 }
 delete pTcpTable;
 }
 
	获取进程 ID 之后就可以获取进程名和路径了。我使用的是CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)方法,在ROCESSENTRY32中没有进程的
 
 路径信息,可以用 GetModuleFileNameEx 函数获得,或是通过
 CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,nPId) 查找进程模块,出现的第一个模块
 就是程序模块,路径存储在me32.szExePath中。这部分代码请参看我的源程序。
 既然要模仿TcpView,当然要有进程图标了。一开始我选择去读取图标资源,但是这种
 方法兼容性不好,比较麻烦,其实只要用ExtractIcon函数就好了。以下是提取代码:
 
	遇到没有图标的程序可以使用系统默认的程序图标,只要调用HICON GetExeIcon(CString strExe,int nIdx = 0)//获取第 nIdx+1 个图标,一般程序
 将 nIdx 设为 0就可以了
 {
 if(strExe == "") return NULL;
 HMODULE hExe = LoadLibrary(strExe);//把EXE 当二进制资源加载
 if (hExe == NULL)
 {
 return NULL;
 }
 int nNum = (int)::ExtractIcon(hExe,strExe,-1);//获取图标数
 if(nNum == 0) return NULL;
 HICON hIcon = ::ExtractIcon(hExe,strExe,nIdx);//提取图标
 FreeLibrary(hExe);//释放资源
 return hIcon;
 }
 
	遇到没有图标的程序可以使用系统默认的程序图标,只要调用GetExeIcon("shell32.dll",2)就好了。要在每一项前面显示图标,需要在视图类的定义中
 添加图像列表指针 CImageList *m_pImgList,并在构造函数中初始化 m_pImgList = new
 CImageList; m_pImgList->Create(16, 16, ILC_COLORDDB|ILC_COLOR32, 8, 8),然后在
 List 添加列的同时将图像列表加入 List : m_list.SetImageList(m_pImgList,
 LVSIL_SMALL)。获取图标句柄后调用m_pImgList->Add(hIcon),返回值为图标在 ImageList
 中的索引,该索引即是InsertItem时设置的图标索引。
 关闭 TCP 连接的方法是用 SetTcpEntry 函数设置连接的状态为:
 MIB_TCP_STATE_DELETE_TCB,下面是具体代码:
 MIB_TCPROW tcprow;
 tcprow.dwLocalAddr = dwLocalIp;//本地 IP地址
 tcprow.dwRemoteAddr = dwRemoteIp;//远程IP 地址
 tcprow.dwLocalPort = ntohs(nLocalPort);//本地端口
 tcprow.dwRemotePort = ntohs(nRemotePort);//远程端口
 tcprow.dwState = MIB_TCP_STATE_DELETE_TCB;//删除连接
 SetTcpEntry(&tcprow);
 
	使用原始套接字可以监听到接收到的所有IP 数据包,只要分析TCP 包和 UDP 包的相关信息就可以得到每个连接的流量信息。每个连接在内存中是以 UpDownInfo 结构体的形式存
 |