【问题标题】:Get List of Sockets with Winsock [closed]使用 Winsock 获取套接字列表 [关闭]
【发布时间】:2014-11-16 10:27:34
【问题描述】:

如何检索进程中所有套接字文件描述符的列表? 是否可以在 Python 中执行此操作,或者我必须在 C 中使用 Winsock 执行此操作?

【问题讨论】:

    标签: python c windows winsock2


    【解决方案1】:

    我不懂 Python,但我认为下面的代码很容易移植。

    我在VxWorks上经常使用下面的方法,很快在Windows上试了试,是否有效。这个想法是简单地迭代套接字(=整数)并检查它们是否有效:

    int iterator;
    int len;
    int option;
    
    for (iterator = 1; iterator < 1024; iterator++)
    {
        len = sizeof(option);
        if (getsockopt((SOCKET)iterator, SOL_SOCKET, SO_TYPE, &option, &len) == 0)   // valid socket?
        {
            /* valid socket found! */
        }
    }
    

    我已经在 Windows 7 上使用以下创建一些套接字的测试应用程序运行它:

    int main ()
    {
        WSADATA wsaData;
        SOCKET s;
        int iterator;
        int option;
        int len;
        struct sockaddr_in sockaddr;
    
    
    
        WSAStartup(MAKEWORD(2, 0), &wsaData);
    
    
        /*
        **  create some sockets...
        */
        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        printf("s=%d\n", s);
    
        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        printf("s=%d\n", s);
        sockaddr.sin_family = AF_INET;
        sockaddr.sin_addr.s_addr = inet_addr("192.168.178.1");
        sockaddr.sin_port = htons(80);
        connect(s, (SOCKADDR *)&sockaddr, sizeof(sockaddr));
    
        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        printf("s=%d\n", s);
        sockaddr.sin_family = AF_INET;
        sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
        sockaddr.sin_port = htons(27015);
        bind(s, (SOCKADDR *)&sockaddr, sizeof(sockaddr));
        listen(s, 10);
    
    
    
        printf("\niterating sockets...\n");
        for (iterator = 1; iterator < 1024; iterator++)
        {
            len = sizeof(option);
            if (getsockopt((SOCKET)iterator, SOL_SOCKET, SO_TYPE, &option, &len) == 0)   // valid socket?
            {
                printf("socket=%d (type=%d)\n", iterator, option);
    
                len = sizeof(option);
                if (getsockopt((SOCKET)iterator, SOL_SOCKET, SO_ACCEPTCONN, &option, &len) == 0)
                {
                    if (option == 0)
                    {
                        len = sizeof(sockaddr);
                        if (getpeername((SOCKET)iterator, (SOCKADDR *)&sockaddr, &len) == 0)
                        {
                            printf("   connected to %d.%d.%d.%d:%d\n",
                                   sockaddr.sin_addr.S_un.S_un_b.s_b1,
                                   sockaddr.sin_addr.S_un.S_un_b.s_b2,
                                   sockaddr.sin_addr.S_un.S_un_b.s_b3,
                                   sockaddr.sin_addr.S_un.S_un_b.s_b4,
                                   sockaddr.sin_port);
                        }
                        else
                        {
                            printf("   ???\n");
                        }
                    }
                    else
                    {
                        len = sizeof(sockaddr);
                        if (getsockname((SOCKET)iterator, (SOCKADDR *)&sockaddr, &len) == 0)
                        {
                            printf("   accepting connections on port=%d\n", sockaddr.sin_port);
                        }
                        else
                        {
                            printf("   accepting connections on port=???\n");
                        }
                    }
                }
            }
        }
    
        return 0;
    }
    

    我得到以下打印输出:

    s=124
    s=132
    s=136
    
    iterating sockets...
    socket=124 (type=1)
       ???
    socket=125 (type=1)
       ???
    socket=126 (type=1)
       ???
    socket=132 (type=1)
       connected to 192.168.178.1:20480
    socket=133 (type=1)
       connected to 192.168.178.1:20480
    socket=134 (type=1)
       connected to 192.168.178.1:20480
    socket=136 (type=1)
       accepting connections on port=34665
    socket=137 (type=1)
       accepting connections on port=34665
    socket=138 (type=1)
       accepting connections on port=34665
    

    有趣的是,Windows 似乎为socket(..) 返回的每个套接字创建了两个额外的套接字。我简单地搜索了互联网以查找有关此的一些信息,但没有找到任何信息...

    【讨论】:

    • 很好的答案,但为什么你会随意停在 1024 处?这是最大的套接字数吗?
    • @user4257726 有一个名为 FD_SETSIZE 的常量(我认为默认为 64),它定义了应用程序的最大套接字数。但是 Windows 开始创建带有偏移量的套接字。所以我只是随机选择了一个大数(相对于 FD_SETSIZE)来获取所有套接字...
    • 但是你不可能这样错过一些套接字吗?难道你不需要达到 MAX_INT 以确保你得到了所有的东西吗?
    • @user4257726 你是对的,确保你必须检查每一个可能的值。但是查看 FD_SETSIZE(相当小)和接近 100 的偏移量,如果您在 10000 处停止迭代,您将处于保存状态。还请记住,每个套接字都需要一些内存(对于 I/O 缓冲区,... ) ,所以你永远不会得到 2^32 个套接字...
    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多