在 Windows 上获取对等套接字的 PID [英] Getting PID of peer socket on Windows

查看:27
本文介绍了在 Windows 上获取对等套接字的 PID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 Web 代理,当有请求(通常来自机器上的浏览器)时,我还想获取 pid 和任何其他请求应用程序.有没有办法使用 Win32 确定这一点?

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?

推荐答案

只有当客户端和服务器在同一台机器上运行时,你的要求才有可能.

What you are asking for is only possible if the client and server are running on the same machine.

当客户端连接到代理时,代理可以使用 getpeername() 查询远程客户端 IP/端口的套接字(或使用 accept() 报告的 IP/端口)和 getsockname() 以获取其本地服务器 IP/端口.然后代理可以使用 GetTcpTable2() (IPv4) 或 GetTcp6Table2() (IPv6) 来检索活动 TCP 连接列表并循环查找与 IP/端口对匹配的连接.如果找到,列表条目将告诉您拥有该连接的进程 ID.

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.

例如:

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

这篇关于在 Windows 上获取对等套接字的 PID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆