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

 导读:html

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

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

 

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

  以前服务端源码:http://www.javashuo.com/article/p-uaclxhvz-kv.htmlubuntu

查阅代码发现,代码主体在while(1)里面,因此最可疑的地方在于accpet,pthread_create, pthread_join和建立的线程client_thread了服务器

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

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.简单完善代码容错机制spa

添加容错代码后之后看看效果如何,代码以下:操作系统

    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);

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

任务完成!

相关文章
相关标签/搜索