我想测试是否在现有套接字上设置了特定的套接字选项。即,几乎所有你能看到的东西:

#!/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套接字编程的文档都是关于创建新的套接字。

有帮助吗?

解决方案

不幸的是,敲门人的答案只捕获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]

其他提示

这在Python中是不可能的。

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

请参阅 lsof FAQ item 3.14.1

Q值。 ‘为什么lsof报告我的方言的套接字选项,套接字状态和TCP标志和值?’。

甲。 '套接字选项,套接字状态,TCP标志和值不能通过/ proc文件系统获得。'

然而,SystemTap的网络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")
}

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top