您的位置:首页 > 运维架构 > Linux

linux socket套接字超时之setsockopt

2016-01-08 00:12 393 查看


概述

对于一个套接字的读写(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套接字选项。这个方法的问题在于并非所有的实现都支持这两个套接字选项。

  上述这三个技术都适用于输入和输出操作(read、write,及其变体recv/send, readv/writev, recvfrom,sendto)。不过我们也期待可以用于connect的技术,因为TCP内置的connect超时相当长(典型值为75秒),而我们在写服务器程序的时候,也不会希望一个连接的建立需要花费这么长时间。select可用来在connect上设置超时的先决条件是相应的套接字是非阻塞的,而那两个套接字选项对connect并不适用;同时也应当指出,前两个技术适用于任何描述符,而第三个技术仅仅适用于套接字描述符。

这里只是测试了下设置套接字超时这种方式.


环境

测试环境:系统debian 6,内核版本:2.6.32-5-686

设置/获取超时代码

SO_RCVTIMEO是接收超时,SO_SNDTIMEO是发送超时.

简单示例.

[cpp] view
plaincopyprint?





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

FROM: /article/1935161.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: