我的代码调用了一个打开TCP服务器套接字的库(在本例中为gstreamer)。我有端口号,但我无权访问文件描述符。
我想从我的应用中检测到当前是否有客户端连接到此端口。理想情况下,我想要一个跨平台的方法(Linux + Mac,* BSD的奖励积分)。
我知道netstat
可以帮助我做到这一点,但我想要一种程序化技术。
答案 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。