一 signale(SIGPIPE,SIG_IGN)
函数的含义
当服务器close一个连接是, 如client端接着发数据,根据tcp协议的规定,
会收到一个RST相应,client再往这个服务器发送数据时,
系统会发出一个SIGPIPE信号给进程,告诉进程这个连接以及断开了, 不要再写了。
如: signal(SIGPIPE,SIG_IGN);
这时SIGPIPE交给了系统处理。
服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生,可以这样处理:
signal(SIGCHLD,SIG_IGN); 交给系统init去回收。 就是忽略该信号
这里子进程就不会产生僵尸进程了。
二解决方法
对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。如果没有调用此方法,系统就会调用默认处理方法:中止程序,显示提示信息(就是我们经常遇到的问题)。
我们可以调用系统的处理方法,也可以自定义处理方法。
(1)SIG_DFL信号专用的默认动作:
(a)如果默认动作是暂停线程,则该线程的执行被暂时挂起。当线程暂停期间,发送给线程的任何附加信号都不交付,直到该线程开始执行,但是SIGKILL除外。
(b)把挂起信号的信号动作设置成SIG_DFL,且其默认动作是忽略信号 (SIGCHLD)。
(2)SIG_IGN忽略信号
(a)该信号的交付对线程没有影响
(b)系统不允许把SIGKILL或SIGTOP信号的动作设置为SIG_DFL
3)SIG_ERR
三 稍微扯远些
什么是RST响应,哪些情况下会产生这个信号的响应(也就是哪些场景会有RST)?
RST响应表示复位,用来异常的关闭连接,
在TCP的设计中不可或缺,发送RST包关闭连接是,不必等缓冲区的包都发出去。
直接就丢弃缓冲区包,发送RST包。 接收端收到RST包后,也不必发送ACK包来确认
一般出现RST错误很难查找原因, 常见的出现RST包的情况
1 服务端端口未打开
服务端程序端口未打开而客户端来连接操作,会出现RST响应的情况。
如客户端发送一个SYN请求,想连接服务端的4001端口,但是服务端没有打开这个端口,
这时服务端就向客户端返回一个RST响应,也有写操作系统不返回RST,直接忽略,
我们做实时在线的server,如果服务器程序 core dump之后重启之前出现RST应该会经常发生。
2 请求超时
3 服务端提前关闭
4 在一个已经关闭的socket上收到数据
如果某个socket已经关闭,但是收到数据也会产生RST
其实在TCP的状态转换图中很少看到RST,因为很少出现,而一旦出现这样RST,你就等着哭吧,真心不知道从哪里查找这个问题
四 再扯下TCP的状态转换图
查了下,好多人写的都非常棒。就不班门弄斧了
阅读(914) | 评论(0) | 转发(0) |