通信架构及锁重构,解决coredump--Apple的学习笔记

诊断系统Linux Server端架构验证--Apple的学习笔记中我列出了5个后续要做的任务,现在已经完成了。新的通信架构验证通过。之前架构的主要问题,就是真实的断线后没有重连。这一把联调是有收获的,故此写下小结。

当前功能:

心跳包处理方案改成了client每隔3s周期发送,server收到则回复一帧心跳(若server此时要发送诊断的回复报文,则跳过一帧心跳)。client在15s内没有收到server发来的任一报文,则关闭socket重连。server端接收超时设置为20s。
实际的断线重连,以及client重连超时后,直接关闭GUI界面退出。server端会关闭与客户端的连接,然后等待新的连接。【其实线断开了,不是完整的关闭,因为client没有回复ack,通过netstat -atp查看,处于FIN_WAIT状态,和协议描述一致,需要2分钟】

一,之前待查任务--已解决

1.python如何正确解析socket的信息格式。resp数据有3DUF乱码。

答:解决方案就是按list一个个取出,然后转为hex。并且每个hex中间添加空格。

            ret = self.s.recv(1024)  # 10
            for i in ret:
                print(hex(i), end=' ')
            print(" ")

2.server端代码需要改成c++11风格。然后确认bb-black开发板是否支持c++11交叉编译工具链。

答:之后改代码,先验证了bb-black arm编译通过,并且效果和在ubuntu上一样。验证通过。


image.png

3.关于锁的应用需要重新设计下

答:client的send函数分布在2个线程中,需要加互斥锁。另外,由于sokect关闭时候send的异常中需要解锁,否则重连后client无法send。
server的send放在同一个线程中,优先回复诊断响应而非回复心跳包。server的锁主要用于接收后设置recv flag,对应的send回复前清recv flag也要上锁。

4. 断线重连要再验证下

答:按原架构,server周期发送心跳,结果断线后send函数不阻塞,后来想起来send只是开辟空间,填充数据,除非填满(什么情况下才填满,暂时没有深入,之后可以详细查询),所以我先认为,不能依靠send来识别断线。只能通过recv来识别断线。
所以重构为client周期发送心跳,server收到心跳后回复一帧。

5.再确认下是否需要用select模式

答:上一个问题已经说明需要用recv来识别断线。recv不能用阻塞的原因是若断线了,recv就一直阻塞,没有办法退出,所以必须要用select了。server端设置了20s。python client端的重连还是检查接收2帧报文的时间超过15s则重连。(python连接函数它自己默认设置了timeout,当然我也可以设置)

二,过程中发现的问题--已解决

1. linux的recv select超时后发生了coredump。

答:原来是buffer数组的长度之前设置为12,后来recv中buffer长度设置为21导致栈溢出,所以函数返回地址被破坏,没法执行return 0。
调试步骤:
a. ulimit -c unlimited
b. gdb ./myDiag core
c. bt full
通过信息看到最后一句出现在437行,就是关闭socket通信后的return 0语句,同时发现buffer的长度不对。

那么一下子想明白了。一定是栈溢出了。原因就是返回地址被buffer溢出的内容覆盖了。栈空间的增长方向是高地址向低地址增长。但是向buffer copy赋值低地址像高地址增长。所以就把epb返回地址覆盖了。导致coredump。
一开始bt full居然没调试信息,后来我在子文件夹的一个cmake文件中也添加了set(CMAKE_BUILD_TYPE "Debug")后,所有调试信息都出来了。

关于栈的详细内容可以参考我之前的blog:Vscode汇编调试出栈入栈—Apple的学习笔记

image.png

2. python client重连超时后,sys.exit(0)后GUI界面无法退出

之前我用的都是sys.exit(0),后来查了由于我现在是python多线程,所以thread.exit和它冲突了。此种情况下要退出shell,使用os._exit(0)可以关闭python进程中所有线程。

三,新架构功能测试通过

image.png

四,添加socketCAN后在arm开发板上验证通过

1.修改send的传输请求数据
2.添加socketCAN线程及server端转发8byte报文内容到socketCAN,等待socketCAN的响应报文后再转发回client端。
3.修改TC275接收721,发送729.
通过命令启动can0,查看can0是否处于normal,启动arm端调试程序,开启candump作为后台CAN报文收发监控。
ip link set can0 type can bitrate 500000
ip link set can0 up
devmem2 0x481d0000
candump can0 &
./myDiag
验证通过截图


image.png

你可能感兴趣的:(通信架构及锁重构,解决coredump--Apple的学习笔记)