tcpip客户端与服务端通讯过程(客户端异常退出导致服务端send函数崩溃)(1)

在linux下编写TCP socket程序时,如果客户端突然退出,导致连接中断,这个时候服务端如果继续调用send函数发送数据的话,会导致整个进程退出,这是我们不愿看到的。(注:如果是服务端突然退出,客户端继续调用send发送,是不会导致进程退出的)。

为什么会退出进程而不是返回一个错误值呢?感觉有点“霸道”,连留给我们处理问题的机会都没有。

原来,当服务端尝试使用一个disconnected socket进行send数据时,会让低层抛出一个SIGPIPE信号,这个信号的缺省处理方法是退出进程!

知道了问题原因后,处理就容易多了,比较简单的方法有以下2种:

重新定义一个信号处理函数,覆盖系统默认处理方法
void signal_process(){ //process code}signa(SIGPIPE, signa_process);

这样,进程就不会退出了。

修改send函数最后一个参数

linux下send函数原型为:

ssize_t send(int fd, const void*buf, size_t n, int flags);

其中,flags被忽略了,一般设置为0,但当flags为0时,如果客户端断开,服务端继续send时,会引发一个信号SIGPIPE,此信号会引发进程退出。

所以只需要把flags设置为MSG_NOSIGNAL,则不会导致信号退出。MSG_NOSIGNAL的含义是,当对方断开连接导致错误时,不发送SIGPIPE信号,但还是会返回EPIPE错误

这样,进程不退出,我们只需要判断send的返回值是否小于或等于0,就知道send函数是否调用成功!

tcpip客户端与服务端通讯过程(客户端异常退出导致服务端send函数崩溃)(2)

,