Python Twisted:出站连接的源IP地址

Python Twisted:出站连接的源IP地址,python,linux,networking,network-programming,twisted,Python,Linux,Networking,Network Programming,Twisted,我正在实现一个服务——用Python编写,使用Twisted框架,运行在Debian GNU/Linux上——检查SIP服务器的可用性。为此,我使用OPTIONS方法(SIP协议特性),因为这似乎是一种常见的做法。为了构造正确且符合RFC的报头,我需要知道要建立的连接的源IP地址和源端口。[如何]使用Twisted可以做到这一点 这就是我所尝试的: 我在startProtocol(self)中使用了self.transport.getHost().host和self.transport.getH

我正在实现一个服务——用Python编写,使用Twisted框架,运行在Debian GNU/Linux上——检查SIP服务器的可用性。为此,我使用OPTIONS方法(SIP协议特性),因为这似乎是一种常见的做法。为了构造正确且符合RFC的报头,我需要知道要建立的连接的源IP地址和源端口。[如何]使用Twisted可以做到这一点

这就是我所尝试的: 我在
startProtocol(self)
中使用了
self.transport.getHost().host
self.transport.getHost().port
。后者确实是将要使用的端口,而前者只产生0.0.0.0


我猜Twisted现在还不知道将使用哪个接口以及哪个源IP地址。Twisted是否提供了一个可以帮助我实现这一点的工具,或者我是否需要以不同的方式与操作系统(路由)接口?或者我只是错误地使用了
self.transport.getHost().host

如果您使用的是UDP,则端点由以下任一项确定:

  • 在套接字上调用
    bind()
    ,并显式地给它一个地址
  • 发送数据包
  • 如果您想了解更多详细信息

    问题是我对twisted不太熟悉。从我对资料来源的快速阅读中可以看出,你可能想用一个类似的反应堆来代替。这是什么

    如果您从图片中取出
    twisted
    ,则以下代码片段将显示发生的情况:

    >>> import socket
    >>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    <socket._socketobject object at 0x10025d670>
    >>> s.getsockname()           # this is an unbound or unnamed socket
    ('0.0.0.0', 0)
    >>> s.bind( ('0.0.0.0', 0) )  # 0.0.0.0 is INADDR_ANY, 0 means pick a port
    >>> s.getsockname()           # IP is still zero, but it has picked a port
    ('0.0.0.0', 56814)
    
    导入套接字 >>>s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0) >>>s.getsockname()#这是一个未绑定或未命名的套接字 ('0.0.0.0', 0) >>>s.bind(('0.0.0.0',0))#0.0.0.0是inaddru ANY,0表示选择端口 >>>s.getsockname()#IP仍然为零,但它已选择了一个端口 ('0.0.0.0', 56814) 如果需要支持多个网络接口或IPv4和IPv6,那么获取主机名就有点麻烦了。如果可以将所使用的接口设置为可配置的,则将其作为元组的第一个成员传递到
    socket.bind()
    ,然后就可以设置了

    现在最困难的部分是在twisted提供的抽象范围内完成这项工作。不幸的是,我在那里帮不了什么忙。我建议您寻找一些示例,说明如何访问底层套接字,或者找到一种将套接字信息传递到框架中的方法


    祝您好运。

    您是否看到,作为Twisted的一部分,您希望通过SIP实现来实现这一点

    在任何情况下,在Twisted中为UDP设置源地址和端口的方式与在没有Twisted的情况下设置源地址和端口的方式非常相似。在Twisted中,
    reactor.listenUDP(端口、协议、接口)
    将UDP套接字绑定到特定的端口和接口,并将接收到的数据报处理到协议中。在协议内部,
    self.transport.write(msg,addr)
    使用协议绑定到的地址作为源地址,向
    addr
    发送数据报


    再次阅读您的问题,我认为您唯一缺少的部分是将
    接口
    传递到
    反应堆。listenUDP(…)

    为了完整性,我回答我自己的问题:

    在尝试确定主机的源IP地址之前,请确保在传输上使用connect()。以下摘录显示了协议实现的相关部分:

    class FooBarProtocol(protocol.DatagramProtocol):
        def startProtocol(self):
            self.transport.getHost().host   # => 0.0.0.0
            self.transport.connect(self.dstHost, self.dstPort)
            self.transport.getHost().host   # => 192.168.1.102
    

    我使用了Twisted的一点SIP实现来生成一些所需的头文件。如果这个问题不是特别关于如何使用Twisted,但在这种情况下,它并没有真正的帮助。Up投票支持你在你发布问题将近一个月后提供一个答案,并使我能够非常简单地将运输对象与自我进行对比。