Python Twisted:出站连接的源IP地址
我正在实现一个服务——用Python编写,使用Twisted框架,运行在Debian GNU/Linux上——检查SIP服务器的可用性。为此,我使用OPTIONS方法(SIP协议特性),因为这似乎是一种常见的做法。为了构造正确且符合RFC的报头,我需要知道要建立的连接的源IP地址和源端口。[如何]使用Twisted可以做到这一点 这就是我所尝试的: 我在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
startProtocol(self)
中使用了self.transport.getHost().host
和self.transport.getHost().port
。后者确实是将要使用的端口,而前者只产生0.0.0.0
我猜Twisted现在还不知道将使用哪个接口以及哪个源IP地址。Twisted是否提供了一个可以帮助我实现这一点的工具,或者我是否需要以不同的方式与操作系统(路由)接口?或者我只是错误地使用了
self.transport.getHost().host
?如果您使用的是UDP,则端点由以下任一项确定:
bind()
,并显式地给它一个地址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投票支持你在你发布问题将近一个月后提供一个答案,并使我能够非常简单地将运输对象与自我进行对比。