python - 发送 CAN J1939 消息
问题描述
我想获得一个代码示例,以使用 Python 使用 J1939 堆栈发送简单的 CAN 消息。
以下网站有一个接收 J1939 消息的简单示例:https ://justkding.me/thoughts/python-sae-j1939-socket-support
此页面上的代码非常适合接收:
import socket
def main():
with socket.socket(
family=socket.PF_CAN, type=socket.SOCK_DGRAM, proto=socket.CAN_J1939
) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
addr = "vcan0", socket.J1939_NO_NAME, socket.J1939_NO_PGN, socket.J1939_NO_ADDR
s.bind(addr)
while True:
data, addr = s.recvfrom(128)
print("{:02x} {:05x}:".format(addr[3], addr[2]), end="")
for j in range(len(data)):
if j % 8 == 0 and j != 0:
print("\n{:05x} ".format(j), end="")
print(" {:02x}".format(data[j]), end="")
print("\n", end="")
if __name__ == "__main__":
main()
我一直在阅读文档,但似乎找不到在 Python 中发送 J1939 消息的简单方法。
这是对内核文档的参考:https ://www.kernel.org/doc/html/latest/networking/j1939.html
这是一个可能有用的 testj1939 的 C 实用程序代码:https ://github.com/linux-can/can-utils/blob/master/testj1939.c
有人可以发布一个简单的代码来使用 Python 中的 J1939 协议发送消息吗?任何显示如何正确执行此操作的文档将不胜感激。
谢谢你。
解决方案
解决方案是使用 sendto() 而不是 send()。在 J1939 中,作为参数提供给 send() 的字节只是有效负载。因此,需要 sendto() 来指定目的地址。
import socket
def main():
s = socket.socket(socket.PF_CAN, socket.SOCK_DGRAM, socket.CAN_J1939)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
addr_source = "vcan0", socket.J1939_NO_NAME, socket.J1939_NO_PGN, 0x20
addr_destination = "vcan0", socket.J1939_NO_NAME, 0x12300, 0x30
s.bind(addr_source)
data = b'\x01\x02\x03\x04\x05\x06\x07\x08'
s.sendto(data, addr_destination)
if __name__ == "__main__":
main()
推荐阅读
- javascript - 在 Rx 中捕获取消订阅错误的建议模式是什么
- c# - 保存/加载登录 cookie Selenium
- javascript - 如何在浏览器中使用 javascript 通过代理服务器发送 HTTP 请求
- xpages - 更改发件人姓名的最佳方法?
- database - Delphi XE10 使用 FORMAT LIKE 过滤数据库表
- javascript - 在 ES6/React 中,如何在列表上下文中引用嵌套对象的键?
- kotlinpoet - 如何动态定义带参数的代码块
- sql - sql查询合并两个表中的数据
- spring - Spring Framework 如何防止跨站点脚本?
- spring-data-jpa - 带有聚合 DTO 的 Spring JPA“PersistentEntity 不能为空”