专栏首页编程入门之C语言Android native进程间通信实例-socket本地通信篇之——服务端进程异常退出解决办法

Android native进程间通信实例-socket本地通信篇之——服务端进程异常退出解决办法

导读:

  好难受啊,为什么服务端说挂就挂,明明只是客户端关闭而已,服务端怎么能挂呢?

想想,如果手机上使用一个聊天程序的时候,手机端关闭了聊天程序,那么远端服务器程序总不能说挂就挂吧!所以一定要查明真相。

1. 跟踪代码查找到进程退出的源头

  之前服务端源码:https://www.cnblogs.com/songsongman/p/11187844.html

查阅代码发现,代码主体在while(1)里面,所以最可疑的地方在于accpet,pthread_create, pthread_join和创建的线程client_thread了

明摆着就是client_thread中出了问题,因为accpet,pthread_create, pthread_join中都有根据函数返回值做是否出错的判断,还是认怂好好看看线程做了什么:

void *client_thread(void *arg)
{
    int clifd = *(int *)arg;char *s = "hello mysocketclient\n";

    while(1)
    {
        usleep(1000000);
        write(clifd,s,strlen(s));//send(clifd,s,strlen(s),0);
    }

    return (void *)0;
}

哇!居然使用write的时候没有添加返回值的判断,在ubuntu终端中输入man 2 write,可以看到write出错时候会返回-1;

2.简单完善代码容错机制

添加容错代码后以后看看效果如何,代码如下:

    while(1)
    {
        usleep(1000000);
        ret = write(clifd,s,strlen(s));//send(clifd,s,strlen(s),0);
        if(ret == -1)
        {
            printf("client thread write failed !\n");
       close(clifd);
            pthread_exit(NULL);
        }
    }

执行结果如下:

过程分析,

1. 先执行服务端程序,然后运行客户端程序,客户端程序强制退出(通过快捷键ctrl+c),服务端client_thread中write返回-1,线程正常退出。

2. 这时候服务端程序还阻塞在accpet等待下一次的客户端连接请求,运行新的客户端程序,然后强制退出客户端,发现服务端进程居然直接退出了!

咋办啊!感觉代码没有任何问题了,为啥还会出错,虽然很明确一定是write的时候没能写进客户端导致的进程奔溃,但是却无从下手。

(注意:为了解决这个问题,笔者绞尽脑汁修改,比如添加

shutdown(clifd, SHUT_RDWR);

又或者添加getsockopt来实时获取连接状态

)效果都不佳,无法解决问题。

3. 添加捕获异常来再次加强容错机制

绞尽脑汁似乎没有什么效果,抓耳挠腮看看吧,好好翻翻书,看看能不能找到灵感。

从网上找到一本和UNIX系统编程有关的书籍《UNIX环境高级编程_第二版中文》,因为android是基于linux开发的操作系统,linux又是从UNIX那边衍射出来的,

所以linux系统编程这块参考这本书特别靠谱。

看到一个和信号有关的章节,确定了要用signal来检测异常,可检测的信号可真多啊!

                    图3.1 参考UNIX环境高级编程第二版中文第10章表1

然后不小心看到这点

好吧,灵感来了,开始写代码,直接添加头文件

#include <signal.h>

然后再main函数中添加signal(SIGPIPE, SIG_IGN);

运行服务端,再运行客户端,不管客户端怎么退出重启,服务端都不受影响了。

任务完成!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • C语言编程入门之--第六章C语言控制语句

    导读:本章带读者理解什么是控制语句,然后逐个讲解C语言常用的控制语句,含有控制语句的代码量多起来后就要注意写代码的风格了,本章末节都是练习题,大量的练习...

    啊源股
  • C语言编程入门之--第五章C语言基本运算和表达式-part4

      二进制数据中,比如一个字节的数据,它的十进制为228,二进制就为11100100,如图5.11,

    啊源股
  • Android native进程间通信实例-socket本地通信篇之——基本通信功能

      网上看了很多篇有关socket本地通信的示例,很多都是调通服务端和客户端通信功能后就没有下文了,不太实用,真正开发中遇到的问题以及程序稳定性部分没有涉及,代...

    啊源股
  • Android Native进程间通信实例—Socket本地通信服务端进程异常退出解决办法

    想想,如果手机上使用一个聊天程序的时候,手机端关闭了聊天程序,那么远端服务器程序总不能说挂就挂吧!所以一定要查明真相。

    Android技术干货分享
  • Android 多语言动态更新方案探索

    最近做的项目需要支持几十种语言,很多小语种在不认识的人看来跟乱码一样,翻译一般是由翻译公司翻译的,翻译完成后再导入到项目里面,这就容易存在一些问题。

    2020labs小助手
  • 解决Pynlpir分词License过期问题

    在Anconda环境下使用pip install pynlpir安装的Pynlpir

    DC童生
  • LintCode-408.二进制求和

    悠扬前奏
  • SSH框架之旅-spring(2)

    Spring 创建对象可以使用配置 xml 文件的方式,也可以使用注解来创建对象,更加的简单。这就需要另外引入一个 spring-aop 的 jar 包,还要在...

    Wizey
  • 2015 华为 校招回忆录---篇(上)

    本文由CSDN-蚍蜉撼青松【主页:http://blog.csdn.net/howeverpf】原创,转载请注明出处!

    bear_fish
  • Flask-信号(blinker)

    简单了解信号 Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。简单来说就是flask在列表里面,预留了几...

    用户1214487

扫码关注云+社区

领取腾讯云代金券