前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个困惑了一个多星期的嵌入式Linux网络编程问题终于解决了!

一个困惑了一个多星期的嵌入式Linux网络编程问题终于解决了!

作者头像
杨源鑫
发布2022-06-10 17:36:46
5150
发布2022-06-10 17:36:46
举报
文章被收录于专栏:嵌入式开发圈嵌入式开发圈

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

  • 由于程序不严谨导致偶现的异常崩溃,进而导致白屏、卡死等现象
  • 在网络通讯过程中,掉线频率非常高
  • 程序结构臃肿,无框架思想

由于公司嵌入式软件方面缺人,而我又是做过嵌入式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信号, 导致进程退出。

参考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问题的解决方案

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

代码语言:javascript
复制
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
sigprocmask(SIG_BLOCK, &set, NULL);

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式应用研究院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、在什么场景下会产生SIGPIPE信号?
  • 2、产生SIGPIPE问题的解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档