• 发生时间:2023-06-14

  • 问题描述:

    • 为方便产线测试时使用 CANFD 设备,我开发了组件 canfd_server,提供通过 HTTP 请求来收发 CAN 报文的服务。
    • 然后使用两台电脑和两个 CANFD 设备来测试,物理连接大概是这样的:电脑1 -- CANFD 1 -- CANFD 2 -- 电脑2
    • 其中电脑1使用 CANFD 自带的上位机软件 BUSMASTER 来发 CAN 报文,电脑2 则使用我开发的 canfd_server 来收报文。
    • 电脑1发出 CAN ID 为 0x222 的报文后,在电脑2 使用 curl 给 canfd_server 发 HTTP 请求,以查询接收到的报文,但一直查不到结果。
  • 问题类别:软件开发

  • 原因分析:

    • 首先把两个 CANFD 设备都接在电脑1,使用 BUSMASTER 来测试收发报文,可以成功,因此排除物理连接问题。
    • 然后在 canfd_server 的源码中打印接收到的请求参数,发现打印的 channel_id 和 can_id 等参数均为0,说明传参出错。
    • 接着查看 libhv (canfd_server 使用的 C++ HTTP 开源库)里面解析请求参数的源码,并逐步加打印日志,最终发现是 JSON 解析报错导致的:
    [json.exception.parse_error.101] parse error at line 1, column 30: syntax error while parsing object - invalid literal; last read: '0x'; expected '}'my json: null
    
    • 网上搜索后发现,原来 JSON 不支持十六进制数字,而我使用 curl 发请求时使用了十六进制数字,导致 canfd_server 解析参数出错而停止后续处理。
    curl -H "Content-Type:application/json" -d '{"channel_id": 2, "can_id": 0x222}' http://192.168.12.182:8081/receive
    
  • 解决方案:使用 curl 发送请求前,先将十六进制转化为十进制。

  • 实施结果:使用 curl 发送请求时,能查询到 canfd_server 接收到的 CAN 报文。

  • 经验总结:

    • JSON 不支持十六进制数字。
    • 排查网络服务问题时,需要先确定是客户端还是服务器的问题,此时可以使用不同的客户端来对比验证。 比如这次的问题,如果我使用 postman 或者其他可视化工具来发送请求,工具会立即提示十六进制数字使用有误,从而能快速定位问题。