我想testing是否已经在现有的套接字上设置了特定的套接字选项。 即,几乎所有你可以看到的:
#!/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
任何人都知道我可以看到现有套接字的选项,即由其他进程创build的选项? 唉几乎所有我在Python套接字编程上阅读的文档都是关于制作新套接字的。
不幸的是,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]
这在Python中是不可能的。
Linux内核不提供/ procfs报告TCP套接字状态的机制(与BSD和其他类Unix操作系统不同)。 由于内核不公开这个信息,我们无法通过python-linux-procfs模块或类似的东西看到它。
请参阅常见问题项目3.14.1的lsof :
问:为什么lsof不报告套接字选项,套接字状态,以及TCP标志和值为我的方言?
A.套接字选项,套接字状态和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关于如何实现这一壮举。