【问题标题】:How does Python access OS API functions such as socket()?Python如何访问socket()等OS API函数?
【发布时间】:2015-07-02 16:50:14
【问题描述】:

更新问题:

  1. 套接字对象实际上是在哪里创建的?我在socketmodule.c 的第 4188 行找到了这个,但它看起来像是叫 sock_new 而不是 socket?

    static PyObject *sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    
  2. 是否有一些约定可以确定像 socketmodule.c 这样的模块的导入位置?换句话说,当我看到“from _socket import *”时,我知道谁在导入什么(无需搜索整个存储库)?


原文:

sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

我试图了解这段代码是如何工作的,具体来说,Python 是如何/在何处实际使 OS 函数调用 socket():

class _socketobject(object):

    __doc__ = _realsocket.__doc__

    __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods)

    def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
        if _sock is None:
            _sock = _realsocket(family, type, proto)
        self._sock = _sock
        for method in _delegate_methods:
            setattr(self, method, getattr(_sock, method))

当我在 Wikipedia 上查找 BSD 套接字时,我看到这个例子很有意义,因为套接字函数是在 types.h 下定义的。在上面我看到一个对 realsocket 的调用,它看起来像一个 OS 函数调用,但我没有在任何地方定义 realsocket(我在 Python27/include 标头中根本看不到任何关于套接字的内容)。

  /* Server code in C */

  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>

  int main(void)
  {
    struct sockaddr_in stSockAddr;
    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

【问题讨论】:

  • 对我来说,Python27/lib 文件夹中有一个 socket.py。文件中有一些描述可用的特定于平台的函数调用的 cmets。
  • Python2.7.10 压缩包中,Modules/socketmodule.c 第 3192 行(在 sock_initobj func 中)fd = socket(family, type, proto);sock_new 只是创建 Python 包装器对象。至于您的第二个问题socket.py 只是_socket.so 的包装器,它公开了动态模块所做的一切(+ 一些事情)。您可以直接导入_socket 并查看其成员。

标签: python sockets


【解决方案1】:

它与 socket.py 中的 1st 和 2nd 行有关:

import _socket
from _socket import *

如果你启动 Python 并运行以下代码:

import socket
print dir(socket)
print dir(socket._socket)

您会注意到,与socket._socket 相比,socket 只导出了一些额外的东西。

现在,socket._socket 是什么?它是一个 Python 动态模块(意味着它可以像任何其他 python 模块一样使用),但它是用 C 编写的(所以编译后它有一个 OS 特定原生形式:Nix 下的 .so.dll (.pyd) 下em>赢)。它的位置在 python lib 文件夹中(socket.py 也位于其中):lib-dynload/_socket*.so

您可以通过打印模块来查看它们的位置(在运行上述代码的同一控制台中,您可以键入):

print socket
print socket._socket

如果您更感兴趣,它的源代码位于 ${PYTHON_SRC_DIR}/Modules/socketmodule.c 中的 Python 源代码压缩包中(它还有一个头文件)。在这些文件中,定义了包装函数(在 Python 中可见)并调用本机函数(例如 中的 socket /usr/include/sys/socket.h).

【讨论】:

  • 这是一个非常有用的答案!谢谢!也帮助我理解了 socketmodule.c!
  • 很高兴为您提供帮助!
猜你喜欢
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多