Python 通过tcp连接到dbus
我编写了一个简单的python程序来播放和暂停女妖音乐播放器。 当它在我自己的机器上工作时,我很难在连接到同一路由器(LAN)的远程计算机上工作。 我编辑了远程机器的session.conf,添加了这一行:Python 通过tcp连接到dbus,python,dbus,Python,Dbus,我编写了一个简单的python程序来播放和暂停女妖音乐播放器。 当它在我自己的机器上工作时,我很难在连接到同一路由器(LAN)的远程计算机上工作。 我编辑了远程机器的session.conf,添加了这一行: <listen>tcp:host=localhost,port=12434</listen> 这就是我尝试执行它时得到的结果 Traceback (most recent call last): File "dbus3.py", line 4, in <m
<listen>tcp:host=localhost,port=12434</listen>
这就是我尝试执行它时得到的结果
Traceback (most recent call last):
File "dbus3.py", line 4, in <module>
bus_obj=dbus.bus.BusConnection("tcp:host=localhost,port=12434")
File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 125, in __new__
bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoServer: Failed to connect to socket "localhost:12434" Connection refused
因此,当我按ctrl+alt+f1组合键时,将session.conf更改为原始状态并重新启动,它将正常引导
这是怎么回事?
如何让dbus守护进程侦听tcp连接而不遇到问题?我最近需要设置它,并发现诀窍是:为
会话.conf中的
元素排序。您应该确保TCP元素首先出现。我知道这很奇怪,但至少对我来说是真的。(如果我颠倒顺序,将UNIX套接字
元素放在第一位,我会看到完全相同的黑屏行为。)
此外,预先添加TCP
标记是必要的,但还不够。要通过TCP实现远程D总线连接,您需要做三件事:
在UNIX标签上方添加一个
标签,如下所示:
<listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
<listen>unix:tmpdir=/tmp</listen>
完成这三件事后,您应该能够远程连接到会话总线。以下是在中指定远程连接时的外观:
请注意,如果您也想连接到系统总线,则需要对/etc/dbus-1/system.conf
进行类似的更改,但需要指定不同的TCP端口,例如55557。(奇怪的是,在这种情况下,元素顺序似乎并不重要。)
在这种配置中,我注意到的唯一奇怪的行为是,运行带有sudo
(例如,sudo gvim
)的桌面应用程序会产生错误或直接失败,并说“没有运行D-BUS守护进程”。但这是我很少需要做的事情,几乎不重要
如果要使用dbus send
发送到远程机器,则需要相应地设置dbus\u SESSION\u BUS\u ADDRESS
,例如:
export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4
即使要发送到的总线实际上是远程机器的系统总线,只要设置与目标上的TCP/etc/dbus-1/system.conf
中的TCP标记相匹配,该功能也可以工作。(多亏了这个提示。直到我偶然发现了他的答案,我才相信dbus-send
支持远程操作。)
更新:如果您正在使用systemd(并且想要访问系统总线),您可能还需要在/lib/systemd/system/dbus.socket
中添加一行,说明ListenStream=5555557
,如下所示:
[Socket]
ListenStream=/var/run/dbus/system_bus_socket
ListenStream=55557 # <-- Add this line
[Socket]
ListenStream=/var/run/dbus/system\u总线\u套接字
ListenStream=55557#自dbus 1.6.12(例如kubuntu 13.10)以来,您的连接也将被拒绝,除非您添加到dbus配置文件(或/etc/dbus-1/mybus.conf或需要远程访问的接口,即system.d/my.interface.conf)
另一个感谢@Shorin,另一个仅供参考-我必须这样做才能让我的工作:
<listen>tcp:host=localhost,bind=0.0.0.0,port=55884</listen>
您必须看到类似于0.0.0.0:55884
的内容,而不是类似于0 127.0.0.1:55884
的默认内容(ubuntu)。对不起,我对网络几乎一无所知,我应该配置iptable以允许连接吗?我认为iptable可以通过默认的有用网络命令实现一切:netstat-na
,lsof-ni
,tcpdump-n-I eth0
和iptables-nvL
。我认为结合使用这些方法可以告诉你,你的过程是否在倾听,如果是的,它是否被某种方式阻止了。祝你好运您可以使用socat
将tcp数据包转发到本地unix套接字,这样您就不需要重新启动dbus守护进程。另外,请尝试tcp:host=0.0.0.0,port=12434
——这将把侦听套接字绑定到所有接口。(检查重启后它是否真的在监听-telnet 192.168.1.7 12434
仅供参考,我需要这样的东西才能工作(注意家族的绑定和设置):tcp:host=localhost,bind=*,port=55884,family=ipv4谢谢,@Shorin。我更新了我的答案,以包含bind
和family
键/值对。我认为并非所有情况下都需要它们(我的答案中没有),并且这些值可能需要针对不同的系统进行调整,但包含它们可能会使答案更完整,对其他人更有帮助。:-)顺便说一句,我在Android设备上尝试了这一点。它在重新启动时挂起。需要闪存才能重新工作。如果您正在努力使dbus在Microsoft的Windows linux子系统上运行,这个答案实际上会有所帮助。@TusharVazirani:您可以使用dbus_SESSION_BUS_ADDRESS
环境变量来指定远程目标,即。,使用类似于DBUS\u SESSION\u BUS\u ADDRESS=tcp:host=192.168.1.17,bind=*,port=55556,family=ipv4./my\u python\u app.py
的方法运行它。(注意:正如我在回答中所提到的,即使您连接的总线实际上是远程机器的系统总线,只要其system.conf
配置为允许通过TCP进行连接,这也可以工作。)
<auth>ANONYMOUS</auth>
<allow_anonymous/>
<listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
<listen>unix:tmpdir=/tmp</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>
export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4
[Socket]
ListenStream=/var/run/dbus/system_bus_socket
ListenStream=55557 # <-- Add this line
<apparmor mode="disabled"/>
IF(EXISTS "/usr/sbin/apparmor_status")
install(FILES dbus_daemon-apparmordisabled.conf RENAME dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ELSE (EXISTS "/usr/sbin/apparmor_status")
install(FILES dbus_daemon.conf DESTINATION /etc/dbus-1/ )
ENDIF(EXISTS "/usr/sbin/apparmor_status")
<listen>tcp:host=localhost,bind=0.0.0.0,port=55884</listen>
netstat -plntu | grep 55884
tcp 0 0 0.0.0.0:55884 0.0.0.0:* LISTEN 707/dbus-daemon