1 背景
写一个c++的TCP通信程序,使用了recv
接口。因为该接口默认为阻塞,因此除非检测到连接断开,否则线程会一直阻塞在那里。
现在需要将recv
接口增加一个超时,即在n秒内未能recv
任何数据,则跳出阻塞。
2 解决方法
解决方法可以有两种:
- 设置
socket
接受超时法:recv
本身可以设置超时(推荐)。
- 信号法:
recv
可以通过信号的方式解除阻塞。
2.1 设置socket超时
在建立连接前增加超时设置:
如此就可以在接收不到任何数据后的3秒时间断开阻塞。
2.2 信号法
我们可以利用信号可以解除阻塞的机制进行,就比如我们利用SIGALRM
信号,可以使用alarm
函数在n
秒后触发信号:
需要注意的是其中的sa_flags
:
- 如果其值为
SA_NOMASK
,则会中断已阻塞的函数,使程序继续往下执行,即略过阻塞。
- 如果其值为
SA_RESTART
,则会重启函数,也就是会复位继续在recv
上阻塞。