概述
对于一个套接字的读写(read/write)操作默认是阻塞的,如果当前套接字还不可读/写,那么这个操作会一直阻塞下去。可以在进行读写操作的时候可以指定超时值,这样就读写操作就不至于一直阻塞下去。
对于非阻塞的套接字立即返回.超时对于阻塞的套接字更有用.
在涉及套接字的I/O操作上设置超时的方法有三种:1:调用alarm,它在指定的超时期满时产生SIGALRM信号。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。
2:在select中阻塞等待I/O(select有内置的时间限制),依次代替直接阻塞在read或write调用上。(linux2.6以后的内核也可以使用epoll的epoll_wait)
3:使用较新的SO_RCVTIMEO和SO_SNDTIMEO套接字选项。这个方法的问题在于并非所有的实现都支持这两个套接字选项。
这里只是测试了下设置套接字超时这种方式.
环境
测试环境:系统debian 6,内核版本:2.6.32-5-686
设置/获取超时代码
SO_RCVTIMEO是接收超时,SO_SNDTIMEO是发送超时.
简单示例.
struct timeval ti;
ti.tv_sec=5;
ti.tv_usec=0;
setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&ti,sizeof(ti));
socklen_t len=sizeof(ti);
getsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,&ti,&len)
TCP设置超时返回错误.
1.接收超时
accept后的socket的设置超时,每次等待读都会生效.
读返回错误-1,errno:EWOULDBLOCK,错误信息Resource temporarily unavailable.
有个有趣的地方在于测试时,服务器端超时已经返回错误了,客户端输入时,使用了两次write函数才报错退出,错误信号为SIGPIPE(Broken pipe).
查了一些资料,第一次write成功,对端返回RST,再次对 RST的套接字/连接write,触发SIGPIPE
信号,程序默认是执行的是退出.这个解释符合现状,也很合理.
参考连接:http://linkyou.blog.51cto.com/1332494/751877/
2.监听套接字超时
bind前/后,listen前/后,在accept前设置超时.
accept后返回-1描述符,errno:EBADF错误信息:Bad file descriptor
这里有个有趣的地方在于,如果监听的套接字设置了超时,由accept衍生出来的套接字都有超时了.如果accept返回的套接字长时间没有读到信息,会返回错误,而且返回的也是EBADF,而不是情形1的EWOULDBLOCK.
3.发送超时
发送超时这里没测试出来,发送的话应该比较快.
UDP套接字超时
监听套接字接收消息,返回结果与TCP情形1样
参考:http://www.cnblogs.com/yuxingfirst/archive/2013/06/06/3120986.html