2016-07-07 67 views
2

我有調用打開TCP服務器套接字的庫(本例中爲gstreamer)的代碼。我有端口號,但我無法訪問文件描述符。如何確定客戶端是否連接到我的套接字?

我想從我的應用程序檢測是否有客戶端當前連接到此端口。理想情況下,我想要一個跨平臺的方法(Linux + Mac,* BSD的加分)。

我知道netstat可以幫助我做到這一點,但我想要一個編程技術。

+0

在Linux上,您可以從'/ proc/net/tcp'中讀取。 – Sergio

+0

爲什麼不能獲取'netstat'的源代碼並查看它是如何完成的? – KevinDTimm

+0

如果你不能通過圖書館本身,它似乎是一個壞主意。我相信gstreamer運行它自己的線程,所以當你檢查並獲得響應(0連接)時,你可能實際上有一個新的連接。 – viraptor

回答

1

庫代碼在進程的地址空間中運行。它使用的文件描述符只是int值,您可以使用getsockopt()查找TCP/IP套接字,然後在那些套接字上使用getpeername()來查找連接的套接字。按照POSIX文件for getsockopt()getpeername()

#include <sys/socket.h> 

// probably better to use getrlimit() here... 
#define MAX_FD 1024 

int tcp_socket_fds[ MAX_FD ]; 
struct sockaddr_in peers[ MAX_FD ]; 

for (int fd = 0; fd < MAX_FD; fd++) 
{ 
    int type; 
    int len = sizeof(type); 

    int rc = getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len);  
    if ((0 == rc) && (SOCK_STREAM == type)) 
    { 
     tcp_socket_fds[ fd ] = 1; 

     socklen_t socket_len = sizeof(peers[ fd ]); 
     rc = getpeername(fd, &(peers[ fd ]), &socket_len); 

     // zero out the peer if getpeername() failed 
     if (0 != rc) 
     { 
      memset(&(peers[ fd ], 0, sizeof(peers[ fd ])); 
     } 
    } 
    else 
    { 
     tcp_socket_fds[ fd ] = 0; 
    } 
} 

這會發現所有連接的TCP套接字的過程中有在檢查的時候打開,它應該是相當便攜。

+0

嗯......我無法完全解析manpage:getpeername'會告訴我客戶端是否連接到我的套接字? – Yoric

+0

@Yoric'getpeername()'的全部目的是告訴你*誰連接到套接字的另一端。這樣做,它會告訴你*如果它已連接。 –

0

擴大Serhio。如果打開的/ proc //網/ TCP和閱讀它,你會看到:

sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode              
    0: 0100007F:0CEA 00000000:0000 0A 00000000:00000000 00:00000000 00000000 116  0 14581 1 ffff880406690000 100 0 0 10 0      
    1: 00000000:008B 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0  0 15646 1 ffff880404aa8700 100 0 0 10 0      
    2: 0100007F:13AD 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000  0 16859998 1 ffff880406692a00 100 0 0 10 0     
    3: 0100007F:F76E 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000  0 31381008 1 ffff8800d7926200 100 0 0 10 0 
... 

從PROC manpage

/proc/net/tcp 
       Holds a dump of the TCP socket table. Much of the information 
       is not of use apart from debugging. The "sl" value is the 
       kernel hash slot for the socket, the "local_address" is the 
       local address and port number pair. The "rem_address" is the 
       remote address and port number pair (if connected). "St" is 
       the internal status of the socket. The "tx_queue" and 
       "rx_queue" are the outgoing and incoming data queue in terms 
       of kernel memory usage. The "tr", "tm->when", and "rexmits" 
       fields hold internal information of the kernel socket state 
       and are useful only for debugging. The "uid" field holds the 
       effective UID of the creator of the socket. 

因此,分析出這些行(跳躍第一行然後sscanf)並從local_address字段中提取端口號以查找您感興趣的端口。查看st字段以查找處於連接狀態的套接字。如果在連接狀態下發現任何內容,則返回true。