【C++】请教下服务端获取客户端IP的问题,附上代码
yann2 2018-05-04 11:49:11 //定义
//--------------------------------
typedef DWORD(WINAPI *_GetExtendedTcpTable)
(
PVOID pTcpTable,
PDWORD pdwSize,
BOOL bOrder,
ULONG ulAf,
TCP_TABLE_CLASS TableClass,
ULONG Reserved
);
static _GetExtendedTcpTable pGetExtendedTcpTable = NULL;
//初始化
//---------------------------------------
HMODULE hIpDLL = LoadLibrary(_T("iphlpapi.dll"));
pGetExtendedTcpTable = (_GetExtendedTcpTable)GetProcAddress(hIpDLL, "GetExtendedTcpTable");
//代码(获取所有链接到本机指定端口的IP信息)
//----------------------------------------
MIB_TCPTABLE_OWNER_PID* pBufTCP = NULL;
DWORD dwBufTCP = 0;
pGetExtendedTcpTable(pBufTCP, &dwBufTCP, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
pBufTCP = (MIB_TCPTABLE_OWNER_PID*)new BYTE[dwBufTCP];
if (NO_ERROR == pGetExtendedTcpTable(pBufTCP, &dwBufTCP, FALSE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0))
{
char strState[50];
struct in_addr inadLocal, inadRemote;
DWORD dwRemotePort = 0;
char szLocalIp[50];
char szRemIp[50];
char szItemText[MAX_PATH] = {0};
UINT uStatus = 0xFF;
for (UINT i = 0; i < pBufTCP->dwNumEntries; i++)
{
switch (pBufTCP->table[i].dwState)
{
case MIB_TCP_STATE_CLOSED:
uStatus = MIB_TCP_STATE_CLOSED;
break;
case MIB_TCP_STATE_TIME_WAIT:
uStatus = MIB_TCP_STATE_TIME_WAIT;
break;
case MIB_TCP_STATE_LAST_ACK:
uStatus = MIB_TCP_STATE_LAST_ACK;
break;
case MIB_TCP_STATE_CLOSING:
uStatus = MIB_TCP_STATE_CLOSING;
break;
case MIB_TCP_STATE_CLOSE_WAIT:
uStatus = MIB_TCP_STATE_CLOSE_WAIT;
break;
case MIB_TCP_STATE_FIN_WAIT1:
uStatus = MIB_TCP_STATE_FIN_WAIT1;
break;
case MIB_TCP_STATE_ESTAB:
uStatus = MIB_TCP_STATE_ESTAB;
break;
case MIB_TCP_STATE_SYN_RCVD:
uStatus = MIB_TCP_STATE_SYN_RCVD;
break;
case MIB_TCP_STATE_SYN_SENT:
uStatus = MIB_TCP_STATE_SYN_SENT;
break;
case MIB_TCP_STATE_LISTEN:
uStatus = MIB_TCP_STATE_LISTEN;
break;
case MIB_TCP_STATE_DELETE_TCB:
uStatus = MIB_TCP_STATE_DELETE_TCB;
break;
default:
uStatus = 0xFF;
break;
}
//已关闭的链接略过
if(uStatus == MIB_TCP_STATE_CLOSED || uStatus == MIB_TCP_STATE_CLOSING) continue;
inadLocal.s_addr = pBufTCP->table[i].dwLocalAddr;
if (strcmp(strState, "LISTEN") != 0)
{
dwRemotePort = pBufTCP->table[i].dwRemotePort;
}
else
dwRemotePort = 0;
//校验端口
u_short uPortCondion = u_short( wPort );
u_short uPortRead = ntohs((unsigned short)(0x0000FFFF & pBufTCP->table[i].dwLocalPort));
if(uPortCondion != uPortRead) continue;
//得到对方IP
inadRemote.s_addr = pBufTCP->table[i].dwRemoteAddr;
memset(szRemIp, sizeof(szRemIp), 0);
strcpy(szRemIp, inet_ntoa(inadRemote));
TCHAR *pszRemIP = CharToTChar(szRemIp);
if(!pszRemIP) continue;
//放入内存
保存这些IP[pszRemIP]到内存
delete[] pszRemIP; pszRemIP = NULL;
}
}
delete[] pBufTCP; pBufTCP = NULL;
=======================================================
=======================================================
=======================================================
以上是我获取本机指定端,例如1234这个端口,所有链接到这个端口的IP地址,这里是没问题的。
问题是下面
//IOCP服务端【用户连接线程】
//-----------------------------------------
while( WAIT_OBJECT_0 != WaitForSingleObject(g_hShutdownEvent, 0) )
{
LPSOCKET_INFORMATION sClientObj = new SOCKET_INFORMATION;
if( (sClientObj->Socket = WSAAccept(m_ListenSocket, (SOCKADDR*)&ClientAddr, &addr_length, NULL, 0)) != SOCKET_ERROR )
{
.....
//保存链接进来的客户端IP地址
//问题就在这里,所有链接进来的客户端IP我都保存了
char *pszIP = inet_ntoa(ClientAddr.sin_addr);
}
}
//BUG现象
//------------------------------------------
服务端保存下来链接进来的IP地址为列表A
上面获取本机指定端口链接的IP为列表B
遍历列表B,然后拿IP去列表A中去查找,结果发现,有小部分IP查询不到!!
比如列表B在1234这个端口得到100个连进来的IP,其中有20多个IP在列表A中查询不到!!
客户端连接到1234端口并不是我的客户端软件去链接,是其他软件,但是客户端都有再多开一个客户端软件,去链接我的服务端,也就是说客户端其他软件连接到1234端口后,多开出来的那个软件都有链接到我的服务端,所以理论说列表A和列表B的IP数量是同步的。
这个BUG困扰我几天了,一直找不到解决办法。。
下面是我最后一次通过对比得出来查询不到的IP:
111.42.30.7
111.44.141.15
111.56.42.206
112.12.31.156
122.190.94.122
122.190.94.125
122.190.94.128
122.190.94.130
122.190.94.140
122.190.94.186
122.190.94.190
122.191.204.109
124.160.153.55
183.198.47.59
183.232.25.133
218.201.223.186
220.203.63.63
223.67.168.108
61.148.103.146
并没有发现有什么不妥的地方,不明白为什么就是总有一部分人IP查询不到。
他们都没有开代理,都是直接连接。
还望各位大神指点迷津,十分感谢!!!!!!!