What you are asking for is only possible if the client and server are running on the same machine.
When a client is connected to the proxy, the proxy can use getpeername()
to query the socket for the remote client IP/Port (or use the IP/Port reported by accept()
) and getsockname()
to get its local server IP/Port. Then the proxy can use GetTcpTable2()
(IPv4) or GetTcp6Table2()
(IPv6) to retrieve a list of active TCP connections and loop through it looking for a connection that matches the IP/Port pairs. If found, the list entry will tell you the process ID that owns that connection.
For example:
DWORD GetClientPid(SOCKET client)
{
DWORD pid = 0;
sockaddr_in ServerAddr = {0};
int ServerAddrSize = sizeof(ServerAddr);
sockaddr_in ClientAddr = {0};
int ClientAddrSize = sizeof(ClientAddr);
if ((getsockname(client, (sockaddr*)&ServerAddr, &ServerAddrSize) == 0) &&
(getpeername(client, (sockaddr*)&ClientAddr, &ClientAddrSize) == 0))
{
PMIB_TCPTABLE2 TcpTable = NULL;
ULONG TcpTableSize = 0;
ULONG result;
do
{
result = GetTcpTable2(TcpTable, &TcpTableSize, TRUE);
if (result != ERROR_INSUFFICIENT_BUFFER)
break;
LocalFree(TcpTable);
TcpTable = (PMIB_TCPTABLE2) LocalAlloc(LMEM_FIXED, TcpTableSize);
}
while (TcpTable != NULL);
if (result == NO_ERROR)
{
for (DWORD dw = 0; dw < TcpTable->dwNumEntries; ++dw)
{
PMIB_TCPROW2 row = &(TcpTable->table[dw]);
if ((row->dwState == MIB_TCP_STATE_ESTAB) &&
(row->dwLocalAddr == ClientAddr.sin_addr.s_addr) &&
((row->dwLocalPort & 0xFFFF) == ClientAddr.sin_port) &&
(row->dwRemoteAddr == ServerAddr.sin_addr.s_addr) &&
((row->dwRemotePort & 0xFFFF) == ServerAddr.sin_port))
{
pid = row->dwOwningPid;
break;
}
}
}
LocalFree(TcpTable);
}
return pid;
}
SOCKET client = accept(server, NULL, NULL);
if (client != INVALID_SOCKET)
{
DWORD ClientPid = GetClientPid(client);
...
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…