日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)

發布時間:2025/3/20 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux 進程間通信 dbus-glib【實例】詳解一(附代碼)(d-feet工具使用)

linux 進程間通信 dbus-glib【實例】詳解二(上) 消息和消息總線(附代碼)

linux 進程間通信 dbus-glib【實例】詳解二(下) 消息和消息總線(ListActivatableNames和服務器的自動啟動)(附代碼)

linux 進程間通信 dbus-glib【實例】詳解三 數據類型和dteeth(類型簽名type域)(層級結構:服務Service --> Node(對象、object) 等 )(附代碼)

linux 進程間通信 dbus-glib【實例】詳解四(上) C庫 dbus-glib 使用(附代碼)(編寫接口描述文件.xml,dbus-binding-tool工具生成綁定文件)

linux 進程間通信 dbus-glib【實例】詳解四(下) C庫 dbus-glib 使用(附代碼)

文章目錄

  • dbus實例講解(二上):消息和消息總線
    • 1、D-Bus的消息
      • 1.1、消息類型
      • 1.2、dbus-send和dbus-monitor
    • 2、消息總線(dbus-daemon?)的方法和信號
      • 2.1、概述
      • 2.2、清單
    • 2.3、練習
      • 2.3.1、從ListName到d-feet的基本邏輯

dbus實例講解(二上):消息和消息總線

應用程序A和消息總線連接,這個連接獲取了一個眾所周知的公共名(記作連接A)。應用程序A中有對象A1提供了接口I1,接口I1有方法M1。 應用程序B和消息總線連接,要求調用連接A上對象A1的接口I1的方法M1。

在上一講的加法例子中,上面這段話可以實例化為:

應用程序example-service和會話總線連接。這個連接獲取了一個眾所周知的公共名“org.fmddlmyy.Test”。
應用程序example-servic中有對象“/TestObj”提供了接口“org.fmddlmyy.Test.Basic”,接口“org.fmddlmyy.Test.Basic”有方法“Add”。
應用程序d-feet和會話總線連接,要求調用連接“org.fmddlmyy.Test”上對象“/TestObj”的接口“org.fmddlmyy.Test.Basic”的方法“Add”。

應用程序B調用應用程序A的方法,其實就是應用程序B向應用程序A發送了一個類型為“method_call”的消息。 應用程序A通過一個類型為“method_return”的消息將返回值發給應用程序B。我們簡單介紹一下D-Bus總線上的消息。

1、D-Bus的消息

上一講說過最基本的D-Bus協議是一對一的通信協議。與直接使用socket不同,D-Bus是面向消息的協議。 D-Bus的所有功能都是通過在連接上流動的消息完成的。

1.1、消息類型

D-Bus有四種類型的消息:

  • method_call 方法調用
  • method_return 方法返回
  • error 錯誤
  • signal 信號

前面介紹的遠程方法調用就用到了method_call和method_return消息。顧名思義,在發生錯誤時會產生error消息。 如果把method_call看作打電話,那么signal消息就是來電了。后面還會詳細討論。

1.2、dbus-send和dbus-monitor

dbus提供了兩個小工具:dbus-send和dbus-monitor。我們可以用dbus-send發送消息。用dbus-monitor監視總線上流動的消息。 讓我們通過dbus-send發送消息來調用前面的Add方法,這時dbus-send充當了應用程序B。用dbus-monitor觀察調用過程中的消息。

啟動example-service:

$ ./example-service

在另一個控制臺啟動dbus-monitor:

$ dbus-monitor

dbus-monitor默認監視會話總線。執行:

$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.fmddlmyy.Test.Basic.Add int32:100 int32:999

輸出為:

method return time=1642572373.469364 sender=:1.124 -> destination=:1.135 serial=118 reply_serial=2int32 1099

dbus-monitor的相關輸出包括:

(我的ubuntu輸出)

signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChangedstring ":1.22"string ""string ":1.22" method call sender=:1.22 -> dest=org.freedesktop.DBus path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=Hello method call sender=:1.22 -> dest=org.fmddlmyy.Test path=/TestObj; interface=org.fmddlmyy.Test.Basic; member=Addint32 100int32 999 method return sender=:1.21 -> dest=:1.22 reply_serial=2int32 1099 signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChangedstring ":1.22"string ":1.22"string ""

:1.22就是dbus-send在本次調用中與會話總線所建立連接的唯一名。:1.21是連接“org.fmddlmyy.Test”的唯一名。 在以上輸出中我們可以看到:1.22向“org.fmddlmyy.Test”發送method_call消息,調用Add方法。 :1.21通過method_return消息將調用結果發回:1.22。其它輸出信息會在以后說明。

dbus-send的詳細用法可以參閱手冊。調用遠程方法的一般形式是:

$ dbus-send [--system | --session] --type=method_call --print-reply --dest=連接名 對象路徑 接口名.方法名 參數類型:參數值 參數類型:參數值

dbus-send支持的參數類型包括:string, int32, uint32, double, byte, boolean。

2、消息總線(dbus-daemon?)的方法和信號

2.1、概述

消息總線(dbus-daemon?)是一個特殊的應用,它可以在與它連接的應用之間傳遞消息。 可以把消息總線看作一臺路由器。正是通過消息總線,D-Bus才在一對一的通信協議基礎上實現了多對一和一對多的通信。

消息總線雖然有特殊的轉發功能,但消息總線也還是一個應用。 其它應用與消息總線的通信也是通過1.1節的基本消息類型完成的。作為一個應用,消息總線也提供了自己的接口,包括方法和信號。

我們可以通過向連接“org.freedesktop.DBus ”上對象“/”發送消息來調用消息總線提供的方法。 事實上,應用程序正是通過這些方法連接到消息總線上的其它應用,完成請求公共名等工作的。

2.2、清單

消息總線對象支持第一講中提到的標準接口"org.freedesktop.DBus.Introspectable", 我們可以調用org.freedesktop.DBus.Introspectable.Introspect方法查看消息總線對象支持的接口。例如:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect
(arm攝像頭上用:[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect)

輸出為:

(arm攝像頭)

[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect method return time=1642579767.439290 sender=org.freedesktop.DBus -> destination=:1.17 serial=3 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><interface name="org.freedesktop.DBus"><method name="Hello"><arg direction="out" type="s"/></method><method name="RequestName"><arg direction="in" type="s"/><arg direction="in" type="u"/><arg direction="out" type="u"/></method><method name="ReleaseName"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="StartServiceByName"><arg direction="in" type="s"/><arg direction="in" type="u"/><arg direction="out" type="u"/></method><method name="UpdateActivationEnvironment"><arg direction="in" type="a{ss}"/></method><method name="NameHasOwner"><arg direction="in" type="s"/><arg direction="out" type="b"/></method><method name="ListNames"><arg direction="out" type="as"/></method><method name="ListActivatableNames"><arg direction="out" type="as"/></method><method name="AddMatch"><arg direction="in" type="s"/></method><method name="RemoveMatch"><arg direction="in" type="s"/></method><method name="GetNameOwner"><arg direction="in" type="s"/><arg direction="out" type="s"/></method><method name="ListQueuedOwners"><arg direction="in" type="s"/><arg direction="out" type="as"/></method><method name="GetConnectionUnixUser"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="GetConnectionUnixProcessID"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="GetAdtAuditSessionData"><arg direction="in" type="s"/><arg direction="out" type="ay"/></method><method name="GetConnectionSELinuxSecurityContext"><arg direction="in" type="s"/><arg direction="out" type="ay"/></method><method name="ReloadConfig"></method><method name="GetId"><arg direction="out" type="s"/></method><method name="GetConnectionCredentials"><arg direction="in" type="s"/><arg direction="out" type="a{sv}"/></method><property name="Features" type="as" access="read"><annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/></property><property name="Interfaces" type="as" access="read"><annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/></property><signal name="NameOwnerChanged"><arg type="s"/><arg type="s"/><arg type="s"/></signal><signal name="NameLost"><arg type="s"/></signal><signal name="NameAcquired"><arg type="s"/></signal></interface><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg direction="out" type="s"/></method></interface><interface name="org.freedesktop.DBus.Peer"><method name="GetMachineId"><arg direction="out" type="s"/></method><method name="Ping"></method></interface><node name="org/freedesktop/DBus"/> </node> " [root@RV1126_RV1109:~]#

從輸出可以看到會話總線對象支持標準接口“org.freedesktop.DBus.Introspectable”和接口“org.freedesktop.DBus”。 接口“org.freedesktop.DBus”有16個方法和3個信號。下表列出了“org.freedesktop.DBus”的12個方法的簡要說明:

(這個表日后可能要做搜索用,附個鏈接:http://www.fmddlmyy.cn/mytext.html)

接口“org.freedesktop.DBus”的3個信號是:

2.3、練習

讓我們來試試消息總線提供的方法。

2.3.1、從ListName到d-feet的基本邏輯

用dbus-send調用:

$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames
(ubuntu里)
輸出為:(略)
(arm攝像頭里)
輸出為:

[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames method return time=1642596554.334145 sender=org.freedesktop.DBus -> destination=:1.13 serial=3 reply_serial=2array [string "org.freedesktop.DBus"string ":1.7"string ":1.8"string "rockchip.netserver"string "org.freedesktop.Avahi"string ":1.13"string ":1.0"string ":1.1"string ":1.2"string ":1.3"string "rockchip.system"string "net.connman"string ":1.4"string "fi.w1.wpa_supplicant1"string "rockchip.dbserver"string ":1.5"string "rockchip.StorageManager"string ":1.6"] [root@RV1126_RV1109:~]#

這是會話總線當前已連接的連接名。在d-feet窗口的左側窗口顯示的就是ListNames返回的連接名。
(ubuntu d-feet軟件)

聰明的讀者也許已經想到使用消息總線的“org.freedesktop.DBus.ListNames”方法和各連接的“org.freedesktop.DBus.Introspectable.Introspect”, 我們就可以像d-feet一樣查看總線上所有連接的所有對象的所有接口的所有方法和信號。

你的想法很好。但有一個問題,我們必須對連接中的對象調用“org.freedesktop.DBus.Introspectable.Introspect”方法。 ListNames只列出了連接名,我們怎么獲取連接中的對象路徑呢?

答案很簡單,如果我們不知道對象路徑就從根目錄開始吧。連接中的對象是按照樹型結構組織的。我們遍歷連接的對象樹就可以找到所有的對象。 調用對象的“org.freedesktop.DBus.Introspectable.Introspect”方法就可以查看對象的所有接口的所有方法和信號。

(如在arm攝像頭里查看"rockchip.netserver"所有方法)

[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver / org.freedesktop.DBus.Introspectable.Introspect method return time=1642598000.976271 sender=:1.4 -> destination=:1.15 serial=19 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/></method></interface><interface name="rockchip.netserver.server"><method name="GetService"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetNetworkIP"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetConfig"><arg name="service" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="ScanWifi"></method><signal name="PowerChanged"><arg name="name" type="s"/><arg name="value" type="v"/></signal></interface> <node name="net"/> </node>" [root@RV1126_RV1109:~]#

例如:假設我們不知道連接"org.fmddlmyy.Test"里有什么對象,我們可以對根對象"/"執行:

$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test / org.freedesktop.DBus.Introspectable.Introspect

(當然,要先運行作者的example-service服務)

輸出為:

[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]1$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test / org.freedesktop.DBus.Introspectable.Introspect method return time=1642599939.774764 sender=:1.89 -> destination=:1.90 serial=8 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><node name="TestObj"/> </node> " [arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]2$

“org.fmddlmyy.Test"的對象樹的根節點只有一個子節點"TestObj”,再查看"/TestObj":

$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.freedesktop.DBus.Introspectable.Introspect

[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]2$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.freedesktop.DBus.Introspectable.Introspect method return time=1642601175.664496 sender=:1.89 -> destination=:1.91 serial=9 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="data" direction="out" type="s"/></method></interface><interface name="org.freedesktop.DBus.Properties"><method name="Get"><arg name="interface" direction="in" type="s"/><arg name="propname" direction="in" type="s"/><arg name="value" direction="out" type="v"/></method><method name="Set"><arg name="interface" direction="in" type="s"/><arg name="propname" direction="in" type="s"/><arg name="value" direction="in" type="v"/></method><method name="GetAll"><arg name="interface" direction="in" type="s"/><arg name="props" direction="out" type="a{sv}"/></method></interface><interface name="org.fmddlmyy.Test.Basic"><method name="Add"><arg name="arg0" type="i" direction="in"/><arg name="arg1" type="i" direction="in"/><arg name="ret" type="i" direction="out"/></method></interface> </node> " [arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]3$

作為一個練習,讓我們來查看系統總線的上的bluez接口。執行:(我發現我沒bluez這個接口😂)

那就在arm攝像頭上看netserver這個接口吧

$ dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames

輸出為:

method return time=1642603380.135709 sender=org.freedesktop.DBus -> destination=:1.22 serial=3 reply_serial=2array [string "org.freedesktop.DBus"string ":1.7"string ":1.8"string "rockchip.netserver"string "org.freedesktop.Avahi"string ":1.22"string ":1.0"string ":1.1"string ":1.2"string ":1.3"string "rockchip.system"string "net.connman"string ":1.4"string "fi.w1.wpa_supplicant1"string "rockchip.dbserver"string ":1.5"string "rockchip.StorageManager"string ":1.6"]

我們看到連接"rockchip.netserver"。查看它的根對象:

$ dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver / org.freedesktop.DBus.Introspectable.Introspect

輸出為:

method return time=1642603716.790027 sender=:1.4 -> destination=:1.24 serial=27 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/></method></interface><interface name="rockchip.netserver.server"><method name="GetService"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetNetworkIP"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetConfig"><arg name="service" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="ScanWifi"></method><signal name="PowerChanged"><arg name="name" type="s"/><arg name="value" type="v"/></signal></interface><node name="net"/> </node>"

繼續找下一層net:
dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver /net org.freedesktop.DBus.Introspectable.Introspect

method return time=1642604470.802829 sender=:1.4 -> destination=:1.25 serial=28 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><node name="connman"/> </node> "

繼續找下一層connman
dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver /net/connman org.freedesktop.DBus.Introspectable.Introspect

method return time=1642604607.622167 sender=:1.4 -> destination=:1.26 serial=29 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><node name="connmanctl629"/> </node> "

繼續:
dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver /net/connman/connmanctl629 org.freedesktop.DBus.Introspectabl e.Introspect

method return time=1642605626.176534 sender=:1.4 -> destination=:1.27 serial=30 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/></method></interface><interface name="net.connman.Agent"><method name="Release"></method><method name="Cancel"></method><method name="RequestBrowser"><arg name="service" type="o" direction="in"/><arg name="url" type="s" direction="in"/></method><method name="ReportError"><arg name="service" type="o" direction="in"/><arg name="error" type="s" direction="in"/></method><method name="ReportPeerError"><arg name="peer" type="o" direction="in"/><arg name="error" type="s" direction="in"/></method><method name="RequestInput"><arg name="service" type="o" direction="in"/><arg name="fields" type="a{sv}" direction="in"/><arg name="fields" type="a{sv}" direction="out"/></method><method name="RequestPeerAuthorization"><arg name="peer" type="o" direction="in"/><arg name="fields" type="a{sv}" direction="in"/><arg name="fields" type="a{sv}" direction="out"/></method></interface> </node> "

調用接口net.connman.Agent里的Cancel方法:(終于調成功了,發現其他幾個都調不成功,是不是參數沒傳對?)

dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver /net/connman/connmanctl629 net.connman.Agent.Cancel

method return time=1642605903.695343 sender=:1.4 -> destination=:1.29 serial=33 reply_serial=2

作者:我們看到了對象"/org/bluez"的所有接口。對象"/org/bluez"還有子節點"service_audio"、“service_input”、“service_network"和"service_serial”。 必要時我們可以接著查下去。d-feet的基本邏輯就是這樣。 后面我們會自己實現一個dteeth。dteeth是命令行程序,可以遍歷指定連接的對象樹,列出所有對象的所有接口的方法和信號。

參考文章:dbus實例講解(二上):消息和消息總線

總結

以上是生活随笔為你收集整理的linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。