不幸的是,正在使用的标准库模块堆栈(urllib2,httplib,socket)为此目的而设计得有些糟糕-
在 *** 作的关键点
HTTPConnection.connect(在httplib中)委托给
socket.create_connection,这反过来使您没有任何“钩子”在创建套接字实例
sock和
sock.connect调用之间,您需要在插入
sock.bind之前插入
sock.connect源IP(我正在广泛传播信息,而不是以这种不密封,过度封装的方式设计抽象-
我我将在本周四的OSCON上以“ Zen和抽象维护的艺术”为标题来谈论这一点-但在这里,您的问题是如何处理我们以这种方式设计的一堆抽象(叹气)。
当您遇到此类问题时,您只有两个不太好的解决方案:要么复制,粘贴并编辑设计错误的代码,然后在代码中放置原始设计人员无法满足的“钩子”。或“猴子补丁”该代码。GOOD都不是,但是两者都可以,所以至少要感谢我们有这样的选择(通过使用开源和动态语言)。在这种情况下,我想我会去进行猴子补丁(这很糟糕,但是复制和粘贴编码甚至更糟)—一个代码片段,例如:
根据您的确切需求(是否需要将所有套接字都绑定到相同的源IP,还是…?),您可以在import sockettrue_socket = socket.socketdef bound_socket(*a, **k): sock = true_socket(*a, **k) sock.bind((sourceIP, 0)) return socksocket.socket = bound_socket
urllib2正常使用之前简单地运行它,或者(当然,以更复杂的方式)仅在需要时运行它。您确实需要以某种方式绑定那些传出的套接字(然后进行每次还原,`socket.socket
true_socket`以避开将来尚未创建的套接字)。第二种替代方法会添加其自身的复杂性以正确编排,因此我在等所有内容解释之前,等待您澄清您是否确实需要此类复杂性。
AKX的好答案是“复制/粘贴/编辑”选项的变体,因此我不需要对此进行太多扩展-
请注意,它并不能完全复制
socket.create_connection其
connect方法,请参见此处的源代码(页末),并决定
create_connection如果您决定采用该功能,则可能希望在复制/粘贴/编辑版本中体现该功能的其他功能。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)