上个月中下旬有一个同事突然从公司离职,而他负责的部分是整个项目里的网络编程模块;这也是我们整个项目里最难,BUG最多的模块。目前这个模块涉及难点主要有以下问题:
- 由于程序不严谨导致偶现的异常崩溃,进而导致白屏、卡死等现象
- 在网络通讯过程中,掉线频率非常高
- 程序结构臃肿,无框架思想
由于公司嵌入式软件方面缺人,而我又是做过嵌入式Linux相关的,于是,这个项目就只能让我来接手了,但由于项目十分紧急,开始我是没有什么把握的,直到后来静下心来调试,慢慢就掌握了整个设备与云端的业务通讯流程。针对与云端联调的问题,最首要的是解决连接的稳定性部分,也就是"在网络通讯过程中,掉线频率非常高"这一项,这样才能确保与云端的同事能够将业务流程顺利进行下去。
针对这个问题,我找了很久,也尝试对程序的逻辑、框架进行优化,但始终定位不到问题点。最后只能使出最常用的招,直接到程序里去打LOG Debug,最终发现在网络发送数据的时候出现了"Broken pipe"这个字段;后来经过复现,发现只要是断线,则百分百出现该字段。因此,我断定这个问题就是"Broken pipe"引起的。
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。
点击这里找小助理0元领取:加微信领取资料
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信号, 导致进程退出。
参考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问题的解决方案
在程序的最开始加入以下代码:
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
sigprocmask(SIG_BLOCK, &set, NULL);
这样就可以避免Program received signal SIGPIPE, Broken pipe。
转载自:嵌入式应用研究院
文章来源于一个困惑了一个多星期的嵌入式Linux网络编程问题终于解决了!
原文链接:
https://mp.weixin.qq.com/s/6IBuGDjrZI2L8SlzKd9RCQ