凡亿专栏 | 一个困惑了一个多星期的嵌入式Linux网络编程问题终于解决了
一个困惑了一个多星期的嵌入式Linux网络编程问题终于解决了

来源 | CSDN & 项目调试

补充 | 嵌入式应用研究院

上个月中下旬有一个同事突然从公司离职,而他负责的部分是整个项目里的网络编程模块;这也是我们整个项目里最难,BUG最多的模块。目前这个模块涉及难点主要有以下问题:

8c967c8e533608fb0aecb052b0ba7e.png

由于程序不严谨导致偶现的异常崩溃,进而导致白屏、卡死等现象
在网络通讯过程中,掉线频率非常高

程序结构臃肿,无框架思想


由于公司嵌入式软件方面缺人,而我又是做过嵌入式Linux相关的,于是,这个项目就只能让我来接手了,但由于项目十分紧急,开始我是没有什么把握的,直到后来静下心来调试,慢慢就掌握了整个设备与云端的业务通讯流程。针对与云端联调的问题,最首要的是解决连接的稳定性部分,也就是"在网络通讯过程中,掉线频率非常高"这一项,这样才能确保与云端的同事能够将业务流程顺利进行下去。

针对这个问题,我找了很久,也尝试对程序的逻辑、框架进行优化,但始终定位不到问题点。最后只能使出最常用的招,直接到程序里去打LOG Debug,最终发现在网络发送数据的时候出现了"Broken pipe"这个字段;后来经过复现,发现只要是断线,则百分百出现该字段。因此,我断定这个问题就是"Broken pipe"引起的。

1、在什么场景下会产生SIGPIPE信号?

如果一个socket在接收到了RST packet之后,程序仍然向这个socket写入数据,那么就会产生SIGPIPE信号。

这种现象是很常见的,譬如说,当client连接到server之后,这时候server准备向 client 发送多条消息,但在发送消息之前,client进程意外崩溃了,那么接下来server在发送多条消息的过程中,就会出现SIGPIPE信号。

对一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0, 这就是常说的表示连接关闭. 但第一次对其调用write方法时, 如果发送缓冲没问题, 会返回正确写入(发送). 但发送的报文会导致对端发送RST报文, 因为对端的socket已经调用了close, 完全关闭, 既不发送, 也不接收数据. 所以, 第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出。

8dcdaf4c9b7fb23cac76c7ac787d6a.png

参考1:https://blog.csdn.net/u014752451/article/details/103354574

参考2:https://blog.csdn.net/u013246898/article/details/52934628

参考3:https://blog.csdn.net/u010821666/article/details/81841755


2、产生SIGPIPE问题的解决方案

在程序的最开始加入以下代码:


4f999640a46632d7183d8f1ff776ac.png

这样就可以避免Program received signal SIGPIPE, Broken pipe。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论