【问题标题】:Creating a socket restricted to localhost connections only创建仅限于本地主机连接的套接字
【发布时间】:2011-01-09 06:52:22
【问题描述】:

我有一个包含许多线程的 python 程序。我正在考虑创建一个套接字,将其绑定到本地主机,并让线程读/写到这个中心位置。但是我不希望这个套接字对网络的其余部分开放,应该只接受来自127.0.0.1 的连接。我将如何做到这一点(在 Python 中)?这是一个合适的设计吗?或者有什么更优雅的吗?

【问题讨论】:

    标签: python client-server


    【解决方案1】:

    如果你这样做 sock.bind((port,'127.0.0.1')) 它只会在 localhost 上侦听,而不是在其他接口上,所以这就是你所需要的。

    【讨论】:

      【解决方案2】:

      给定一个使用socket.socket() 创建的套接字,您可以在收听之前使用bind()

      socket.bind(('127.0.0.1', 80))
      

      使用地址127.0.0.1表示套接字应该只绑定到本地接口。

      【讨论】:

      • 这不是绑定到INADDR_ANY吗?
      • 不符合 amk.ca/python/howto/sockets 尽管实际的 Python 文档指出 '' 等同于 INADDR_ANY。我会更新我的答案。
      • 它绑定到 INADDR_ANY 如果你告诉它(通过指定一个主机'')。指定主机 '127.0.0.1' 将其绑定到 127.0.0.1
      【解决方案3】:

      http://www.amk.ca/python/howto/sockets/

      显示一些套接字示例。我觉得这个花絮对你来说很有趣

      我们使用了 socket.gethostname() 以便外界可以看到该套接字。如果我们使用 s.bind(('', 80)) 或 s.bind(('localhost', 80)) 或 s.bind(('127.0.0.1', 80)) 我们仍然会有一个“服务器" 插座,但只有在同一台机器中才能看到。

      我想这就是你的答案(请参阅下面的更正

      关于使用这种方法进行线程通信的有效性。我不确定这处理多线程和读/写的效果如何

      编辑

      下面似乎链接了一个 python 配方,可以进行一些线程间通信

      http://code.activestate.com/recipes/491281/

      玩得开心!

      编辑

      文章不正确,并指出“s.bind(('', 80)) 将绑定到 INADDR_ANY

      【讨论】:

      • 那篇文章不正确。 s.bind(('', 80)) 将绑定到 INADDR_ANY。
      【解决方案4】:

      您可能想改用标准库中的queue module。它专为促进线程之间的通信而设计。来自文档的引用:

      Queue 模块实现了多生产者、多消费者队列。当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用。该模块中的 Queue 类实现了所有必需的锁定语义。这取决于 Python 中线程支持的可用性;查看线程模块。

      【讨论】:

        【解决方案5】:

        如果您在基于 UNIX 的系统上运行,您可能需要考虑使用 UNIX Domain Sockets 而不是 Internet 套接字。我认为类似以下的方法应该有效:

        >>> # in one window/shell
        >>> import socket
        >>> sd = socket.socket(socket.AF_UNIX)
        >>> sd.bind('/path/to/my/socket')
        >>> sd.listen(5)
        >>> (client,addr) = sd.accept()
        >>> client.recv(1024)
        'hello'
        >>>
        
        >>> # in a different shell
        >>> import socket
        >>> sd = socket.socket(socket.AF_UNIX)
        >>> sd.connect('/path/to/my/socket')
        >>> sd.send('hello')
        

        【讨论】:

        • 在环回设备上使用 TCP/IP 套接字的优点(或缺点,如果你愿意的话)可以通过 SSH 隧道进行访问。
        • UNIX 域套接字提供了相同的功能,因为它绑定到文件系统。我倾向于使用它们,因为它们不像 IP 套接字那样占用大量资源。
        【解决方案6】:

        notionOn TCP/IP 网络 127.0.0.0/8 是一个不可路由的网络,因此您应该无法通过路由基础设施发送一个以 127.0.0.1 为目的地的 IP 数据报。路由器只会丢弃数据报。但是,可以构造和发送目标地址为 127.0.0.1 的数据报,因此与您的主机位于同一网络(IP 意义上的网络)上的主机可能会将数据报获取到您主机的 TCP/IP 堆栈。这就是您的本地防火墙发挥作用的地方。您的本地(主机)防火墙应该有一个规则,该规则丢弃发往 127.0.0.0/8 的 IP 数据报进入除 lo0 以外的任何接口(或等效的环回接口)。如果您的主机 1) 具有此类防火墙规则或 2) 存在于其自己的网络上(或仅与完全受信任的主机共享)并且位于配置良好的路由器后面,您可以安全地绑定到 127.0.0.1 并相当确定任何您在套接字上收到的数据报来自本地机器。前面的答案解决了如何打开和绑定到 127.0.0.1。

        【讨论】:

          猜你喜欢
          • 2016-07-09
          • 2010-09-11
          • 2013-01-28
          • 1970-01-01
          • 2013-07-27
          • 1970-01-01
          • 1970-01-01
          • 2016-05-16
          • 2013-01-30
          相关资源
          最近更新 更多