【问题标题】:Python ioctl error on Mac OSMac OS 上的 Python ioctl 错误
【发布时间】:2012-12-15 05:07:46
【问题描述】:

我正在尝试在 Mac 上运行以下函数,但它正在抛出

struct.pack('iL', bytes, names.buffer_info()[0])
IOError: [Errno 102] Operation not supported on socket

它在 linux 上运行良好。谁能告诉我这是怎么回事?


代码:

def _get_interface_list():
max_iface = 32  # Maximum number of interfaces(Aribtrary)
bytes = max_iface * 32
is_32bit = (8 * struct.calcsize("P")) == 32  # Set Architecture
struct_size = 32 if is_32bit else 40

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
    s.fileno(),
    0x8912,  # SIOCGIFCONF
    struct.pack('iL', bytes, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return namestr

【问题讨论】:

  • 你确定 IOCTL 代码(即SIOCGIFCONF 的实际值)在 OSX 和 Linux 中是一样的吗?
  • 其实我不是。我试过环顾四周,但似乎找不到 Mac 特定 ioctl 的文档,也找不到标志列表/十六进制值表。 ://
  • 找出系统头文件的位置,并在其中搜索文本SIOCGIFCONF
  • 我查阅了 unix 手册页,上面写着“0x00008912”,这似乎与我使用的相同。我正在检查头文件。
  • @DavidRobertsson 你说得对SIOCGIFCONF。我想说的是Mac OS X 不支持SIOCGIFHWADDR。我会相应地更新我的答案。谢谢指出!

标签: python macos sockets system-calls ioctl


【解决方案1】:

SIOCGIFCONF 的标志值在 OS X 10.9 上为 0xc00c6924。

更新

我做了一些小测试,并没有抛出任何错误。我不确定它是否 100% 正常工作,但我也从 Apple 找到了这个:https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man4/ip.4.html where "addr" is the local IP address of the desired interface or INADDR_ANY to specify the default interface. An interface's local IP address and multicast capability can be obtained via the SIOCGIFCONF and SIOCGIFFLAGS ioctls. Normal applications should not need to use this option.

【讨论】:

    【解决方案2】:

    问题在于 Mac OS X 和其他 BSD 系统不支持SIOCGIFHWADDR。您必须使用 getifaddrs,现在 Linux 也支持它,尽管 Python 似乎没有公开它。但是,您可以使用 ctypes 来完成此操作。我希望 this example(BSD 风格的许可证)对您有所帮助。

    此外,您可以使用 netifaces 轻松避免所有麻烦。

    【讨论】:

    • 我将 netifaces 视为我的第一选择,但由于政策原因,我无法使用它。我想知道 Mac OS X 和其他 BSD 系统不支持 SIOCGIFCONF 是否有特定原因,因为函数和 SIOCGIFCONF 实际上是在系统库中定义的?
    • @Ayos 我不知道确切的原因,但getifaddrsSIOCGIFCONF 更受欢迎。我确实更新了一个实际有效的示例的链接。您可以将其用作print [str(ni) for ni in getifaddrs()]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2016-03-28
    • 2013-01-07
    • 2016-08-15
    • 2019-04-01
    相关资源
    最近更新 更多