socket编程之错误断开

来源:互联网 发布:淘宝店铺logo在线制作 编辑:程序博客网 时间:2024/06/05 15:49




最近在做socket编程,遇到一些非人类bug,相信很多人类在工作中也会遇到,所以在这里将之公知于众。
废话不多唆,开始上干货。
环境介绍:
    操作系统ubuntu14
    编译器 gcc4.8
目标功能:实现server端的不间断工作,可正确处理链接断开,和错误信号,确保server端的稳定性
实现思路:server端建立socket链接,发送接受数据同时处理异常,并解决在建立链接后,由于client断开后,server端收SIGPIPE信号自动退出进程问题
client能正常发送接受数据。
问题出现:当client断开后,server端在调用recv函数后,在unix系统中recv在线路错误时会返回终止信号,操作系统收到终止信号会自动退出进程。如果这样写server端,那么server会丑不要脸的持续运行,以至于把SIGPIPE信号忽视掉。
伪代码如下:


<span style="font-family: Arial, Helvetica, sans-serif;">int main()</span>
{     int servfd, clifd;
     servfd = socket();
<span style="font-family: Arial, Helvetica, sans-serif;">     bind();</span>
     listen();
     while(1){
              clifd = accept();
              while(1){
                            revc();
                           send();
               }
    }}


在上面这样的server端代码中,当链接被建立起来,client端退出后,server端在调用recv函数后,会直接跳到accept处执行。这样server端就不会终止进程了。

我都想哭了,就因为这个问题脑细胞死了多少,你们知道吗?

为什么server没有直接终止进程呢?因为进程收到SIGPIPE信号,如果没有自己处理信号,系统会将这个信号转化位break;

对能没看错,是break,然而server端在recv处执行break并不会终止进程,因为break会先调出当前while,这样server就臭不要脸的继续执行了。


话说这样的代码是不健壮的,因为我们在开发socket中,往往要对recv/send函数进行封装,一旦封装recv,那么他就不能正确处理SIGPIPE信号了。

正确做法是使用signal()函数对SIGPIPE信号进行处理

其实在嵌入式项目中,要处理的信号还很多,因为cpu在执行过程中可能收到各种各样你没有不想看到的信号,而这些信号可能直接把你的程序kill掉。。。。。。。。。。


以上就是我的悲催史,希望以后不会在更新类似的博客了。

希望大家关注我的帐号,一起成长!!

enjoy the fucking code!

good LUCK!

0 0