一个简单的基于Python 3 和 DBus 的发送与接收程序示例

DBus 是一个高级的消息传递系统,它允许应用程序和组件通过消息进行通信。它通常用于进程间通信(IPC),相同或不同语言的程序或程序模块都能使用它。在 Python 中,我们可以利用 DBus 实现两个程序(发送者和接收者)之间的通信。

2、解决方案
我们使用 Python 3 和 DBus bindings(使用 gi.repository.GLib)来实现一个发送和接收程序,以便进行基本的通信。代码分为以下几个部分:

common.py:包含一些公共变量和常量,例如,设置我们的程序的名称、接口和路径。

server.py:包含服务器端程序的逻辑。它创建一个 DBus 服务对象(EchoServerObject),实现两个接口(EchoInterface 和 QuitInterface),提供回显消息和退出服务的函数。

client.py:包含客户端程序的逻辑。它获取 DBus 服务并调用服务对象的方法来发送消息。

为了让程序工作,需要先启动服务器端(server.py),然后启动客户端(client.py)发送消息。

完整的代码示例:

common.py:

# 设置我们的程序的名称、接口和路径。
ECHO_BUS_NAME = 'com.stackoverflow.question_21793826.EchoService'
ECHO_INTERFACE = 'com.stackoverflow.question_21793826.EchoInterface'
QUIT_INTERFACE = 'com.stackoverflow.question_21793826.QuitInterface'
ECHO_OBJECT_PATH = '/EchoServerObject'

server.py:

#!/usr/bin/env python3

# 导入必要的库。
import sys
import gi.repository.GLib
import dbus
import dbus.service
import dbus.mainloop.glib
import common

class EchoServerObject(dbus.service.Object):
    # 定义回显消息的方法。
    @dbus.service.method(common.ECHO_INTERFACE,
            in_signature='s', out_signature='')
    def echo(self, message):
        message = str(message) # 确保消息是字符串类型。
        print('server: a client said %r' % message)

    # 定义退出程序的方法。
    @dbus.service.method(common.QUIT_INTERFACE,
            in_signature='', out_signature='')
    def quit(self):
        # 这应该是一个单独的对象,但我们这里展示一个对象可以有多个接口的情况。
        self.mainloop.quit()

def stop():
    # 获取 DBus 会话总线。
    bus = dbus.SessionBus()

    # 获取代理对象。
    proxy = bus.get_object(common.ECHO_BUS_NAME, common.ECHO_OBJECT_PATH)
    iface = dbus.Interface(proxy, common.QUIT_INTERFACE)

    # 调用服务对象的退出方法。
    iface.quit()

def server():
    # 设置 DBus 主循环。
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    # 获取 DBus 会话总线。
    bus = dbus.SessionBus()

    try:
        # 注册 DBus 服务名称。
        name = dbus.service.BusName(common.ECHO_BUS_NAME, bus, do_not_queue=True)
    except dbus.NameExistsException:
        # 如果服务名称已被注册,则退出程序。
        sys.exit('Server is already running.')
    else:
        # 输出服务启动信息。
        print('Server is not running yet. Putting on listening ears.')

    # 创建服务对象。
    echo = EchoServerObject(bus, common.ECHO_OBJECT_PATH)

    # 获取主循环。
    mainloop = gi.repository.GLib.MainLoop()
    echo.mainloop = mainloop

    # 运行主循环。
    mainloop.run()

def main(exe, args):
    if args == ['stop']:
        stop()
    elif not args:
        server()
    else:
        # 输出错误用法信息并退出程序。
        sys.exit('Usage: %s [stop]' % exe)

if __name__ == '__main__':
    main(sys.argv[0], sys.argv[1:])

client.py:

#!/usr/bin/env python3

# 导入必要的库。
import sys
import dbus
import common

def client(mes):
    # 获取 DBus 会话总线。
    bus = dbus.SessionBus()

    try:
        # 获取代理对象。
        proxy = bus.get_object(common.ECHO_BUS_NAME, common.ECHO_OBJECT_PATH)
    except dbus.DBusException as e:
        # 处理异常情况。
        if e._dbus_error_name != 'org.freedesktop.DBus.Error.ServiceUnknown':
            raise
        if e.__context__._dbus_error_name != 'org.freedesktop.DBus.Error.NameHasNoOwner':
            raise
        print('client: No one can hear me!!')
    else:
        # 获取接口对象。
        iface = dbus.Interface(proxy, common.ECHO_INTERFACE)

        # 调用服务对象的回显消息方法。
        iface.echo(mes)

def main(exe, args):
    if args:
        client(' '.join(args))
    else:
        # 输出错误用法信息并退出程序。
        sys.exit('Usage: %s message...' % exe)

if __name__ == '__main__':
    main(sys.argv[0], sys.argv[1:])

运行程序:

  1. 启动服务器程序:
python3 server.py
  1. 启动客户端程序,发送消息:
python3 client.py Hello, world!
  1. 观察服务器端的输出:
server: a client said "Hello, world!"
  1. 停止服务器程序:
python3 server.py stop
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值