1. SIGPIPE信号
当向读端已经关闭的管道或套接字中写数据会引发SIGPIPE信号,而该信号默认结束进程,而我们绝对不希望因为错误的写操作而导致程序退出,引起SIGPIPE信号的写操作设置errno为EPIPE。在代码中需要不会并处理该信号,至少需要忽略它。
避免写操作触发SIGPIPE的方法:
通过send函数的MSG_NOSIGNAL来禁止触发SIGPIPE信号,这种情况如果send返回-1,应该根据errno的值来判断管道或socket连接的读端是否已经关闭。
还可以利用I/O复用系统调用来检测管道和socket的读端是否已经关闭,以poll为例,当管道读端关闭时,写端文件描述符上的POLLHUP事件将被触发;当socket连接被对方关闭时,socket上的POLLRDHUP事件将会触发。
因此注册事件的events还需要加上POLLHUP或POLLRDHUP。对于epoll则是EPOLLHUP和EPOLLRDHUP。
实测:当对端关闭时POLLRDHUP和POLLIN同时被触发!
2. SIGURG信号
内核通知应用程序带外数据到达主要有两种方法:
I/O复用:返回socket的异常事件;
发送SIGURG信号。
3. Linux的三种定时方法
socket选项SO_RCVTIMEO和SO_SNDTIMEO;
SIGALRM信号;
I/O复用系统调用的超时参数。
4. socket选项SO_RCVTIMEO和SO_SNDTIMEO
仅对与数据接收和发送相关的socket专用系统调用有效,send, sendmsg, recv, recvmsg, accept, connect。
send 返回-1,设置errno为EAGAIN或EWOULDBLOCK;
sendmsg 返回-1,设置errno为EAGAIN或EWOULDBLOCK;
recv 返回-1,设置errno为EAGAIN或EWOULDBLOCK;
recvmsg 返回-1,设置errno为EAGAIN或EWOULDBLOCK;
accept 返回-1,设置errno为EAGAIN或EWOULDBLOCK;
connect 返回-1,设置errno为EINPROGRESS