如何确定客户端是否已连接到我的套接字?

时间:2016-07-07 14:57:49

标签: c sockets unix posix

我的代码调用了一个打开TCP服务器套接字的库(在本例中为gstreamer)。我有端口号,但我无权访问文件描述符。

我想从我的应用中检测到当前是否有客户端连接到此端口。理想情况下,我想要一个跨平台的方法(Linux + Mac,* BSD的奖励积分)。

我知道netstat可以帮助我做到这一点,但我想要一种程序化技术。

2 个答案:

答案 0 :(得分: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套接字,并且它应该是相当便携的。

答案 1 :(得分:0)

扩展Serhio。如果你打开/ proc // net / 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。