获取使用Winsock的套接字列表

问题描述:

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

我不知道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(..)返回插座两个额外的插槽。我简单地搜索了互联网找到一些关于这方面的信息,但没有发现任何东西...

+0

很好的答案,但为什么你仲裁停在1024?这是套接字的最大数量吗? – user4257726

+0

@ user4257726有一个常量叫做FD_SETSIZE(默认情况下= 64),它定义了应用程序的套接字的最大数量。但Windows开始创建具有偏移量的套接字。所以我只是随机挑选了大量的数据(关于FD_SETSIZE)来获取所有套接字... –

+0

BUT难道你不可能错过某些套接字吗?难道你不得不去MAX_INT以确保你得到了它们全部? – user4257726