您的位置:首页 > 编程语言

socket编程之错误断开

2016-04-15 11:41 316 查看
最近在做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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: