4

我想测试是否在现有套接字上设置了特定的套接字选项。即,您可以在其中看到的几乎所有内容:

#!/usr/bin/env python
'''See possible TCP socket options'''

import socket

sockettypelist = [x for x in dir(socket) if x.startswith('SO_')]
sockettypelist.sort()
for sockettype in sockettypelist:
    print sockettype

任何人都知道我如何查看现有套接字上的选项,即由其他进程创建的选项?唉,我读过的关于 Python 套接字编程的几乎所有文档都是关于制作新套接字的。

4

3 回答 3

2

这在 Python 中是不可能的。

Linux 内核在 /procfs 中没有提供报告 TCP 套接字状态的机制(与 BSD 和其他类 Unix 操作系统不同)。由于内核不公开此信息,我们无法通过 python-linux-procfs 模块或类似模块看到它。

请参阅lsof 常见问题解答项目 3.14.1

问:“为什么 lsof 不为我的方言报告套接字选项、套接字状态以及 TCP 标志和值?”。

A. '套接字选项、套接字状态以及 TCP 标志和值不能通过 /proc 文件系统获得。

然而 SystemTap 的 Network tapset 提供了一个 tcp.setsockopt 断点,它可以用来拦截进程设置的套接字选项,但是这将在 stap 而不是 python 中处理。

我创建了所需的 Tapset,如下所示:

# Show sockets setting options

# Return enabled or disabled based on value of optval
function getstatus(optlen)
{
    if ( optlen == 1 )
        return "enabling"
    else
        return "disabling"
}

probe begin
{
    print ("\nChecking for apps making socket calls\n")
}

# See apps setting a socket option 
probe tcp.setsockopt
{
    status = getstatus(user_int($optval))
    printf ("  App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
}

# Check setting the socket option worked
probe tcp.setsockopt.return
{
    if ( ret == 0 )
        printf ("success")
    else
        printf ("failed")
    printf ("\n")    
}


probe end
{
    print ("\nClosing down\n")
}
于 2010-03-15T16:20:04.707 回答
2

不幸的是,nailer 的答案仅捕获 SOL_TCP 级别的套接字选项,而不是 SOL_SOCKET 级别的选项(如 SO_KEEPALIVE)。

一些发行版与 systemtap 一起提供了一些示例。其中之一是 pfiles.stp,您可以使用它从正在运行的进程的套接字中获取套接字选项。文件中的示例:

$ ./pfiles.stp `pgrep udevd`
   787: udevd
  Current rlimit: 32 file descriptors
   0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
      O_RDONLY 
      inotify
   4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2353]
      SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
        sockname: AF_UNIX
   5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2354]
      SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
        ulocks: rcv
   6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_RDONLY|O_NONBLOCK 
      pipe:[2355]
   7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_WRONLY|O_NONBLOCK 
      pipe:[2355]
于 2013-03-06T09:08:03.283 回答
1

套接字库确实是为了创建新的套接字并对其进行操作。出于明显的安全原因,在其他进程中创建的套接字不可见:您不希望任何随机应用程序更改您管理自己的套接字的方式,或者更糟糕的是从您的套接字读取数据。所以套接字是系统对象,由句柄引用,具有(在体面的操作系统上)适用于它们的访问权限。这就是为什么您不能列出由其他进程创建的现有套接字的原因。

最终,您可能会找到一种方法来检索套接字句柄(应该有一种方法,我记得在 Windows 上看到了一种列出系统句柄的方法),但这仍然非常特定于您的操作系统,因此在 python 中可能不可用,而且您可能仍然无权在这些套接字上执行任何操作。

现在,如果您只是想知道特定应用程序如何实现特定功能,还有其他方法:最明显的是安装代理或防火墙(我记得我的 Kerio WinRoute 防火墙列出了套接字选项),或者只是询问 stackoverflow关于如何实现这一壮举。

于 2009-10-24T14:30:34.127 回答