套接字选项SO_RCVTIMEO: 用来设置socket接收数据的超时时间; 套接字选项SO_SNDTIMEO: 用来设置socket发送数据的超时时间;
比如,一般情况下,调用accept/connect/send/recv, 进程会阻塞,但是如果对端异常,进行可能无法正常退出等待。如何让这些调用自动定时退出? 可以使用诸如alarm定时器、I/O复用设置定时器,还可以使用socket编程里函数级别的socket套接字选项SO_RCVTIMEO和SO_SNDTIMEO,仅针对与数据接收和发送相关,而无需设置专门的信号捕获函数。
能够作用的系统调用包括:send、sendmsg、recv、recvmsg、accept、connect。
| 系统调用 | 有效选项 | 系统调用超时后的行为 |
|---|---|---|
| send | SO_SNDTIMEO | 返回-1,设置errno为EAGAIN或EWOULDBLOCK |
| sendmsg | SO_SNDTIMEO | 返回-1,设置errno为EAGAIN或EWOULDBLOCK |
| recv | SO_RCVTIMEO | 返回-1,设置errno为EAGAIN或EWOULDBLOCK |
| recvmsg | SO_RCVTIMEO | 返回-1,设置errno为EAGAIN或EWOULDBLOCK |
| accept | SO_RCVTIMEO | 返回-1,设置errno为EAGAIN或EWOULDBLOCK |
| connect | SO_SNDTIMEO | 返回-1,设置errno为EINPROGRESS |
注意
-
EAGAIN通常和EWOULDBLOCK是同一个值;
-
SO_RCVTIMEO, SO_SNDTIMEO不要求系统调用对应fd是非阻塞(nonblocking)的,但是使用了该套接字选项的sock fd,会成为nonblocking(即使之前是blocking)的。参见man手册ERRORS EAGAIN/EWOULDBLOCK的描述;
man send关于EAGAIN / EWOULDBLOCK描述:
EAGAIN or EWOULDBLOCK The socket is marked nonblocking and the requested operation would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.
示例1:设置connect超时时间
根据系统调用accept的返回值,以及errno判断超时时间是否已到,从而决定是否开始处理超时定时任务。
客户端程序:超时连接服务器
/*

本文介绍了如何使用套接字选项SO_RCVTIMEO和SO_SNDTIMEO来设置socket接收和发送数据的超时时间,以避免进程因等待对端响应而无限期阻塞。当超时发生时,相关系统调用将返回-1并设置errno为EAGAIN或EWOULDBLOCK。文中提供了两个示例,一个是设置connect超时,另一个是设置recv超时,展示了如何在客户端和服务器端实现超时机制。
最低0.47元/天 解锁文章
6661

被折叠的 条评论
为什么被折叠?



