Getting PID of peer socket on Windows

天涯浪子 提交于 2019-12-29 09:17:15

问题


I am writing a web proxy and when a request comes in (typically from the browser on the machine), I'd like to also get the pid and any other requesting application. Is there any way to determine this using Win32?


回答1:


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);
    ...
}


来源:https://stackoverflow.com/questions/25429887/getting-pid-of-peer-socket-on-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!