接口阻塞问题解决

【问题一:gethostbyname阻塞卡死】复现条件多为域名解析过程中遇到与DNS服务器断开的情况(如路由器重启)。
【解决方法】首先使用gethostbyname_r函数保证线程安全;再通过修改DNS的配置文件/etc/resolv.conf来设置超时时间解决阻塞问题。
【问题二:SSL_connect卡死】复现条件不明确,推测网络复杂时易出现。网查该函数默认有超时时间,但实测会永久阻塞,怀疑与使用的wolfssl库配置参数有关。
【解决方法】首先将socket改为非阻塞:fcntl(hHandle, F_SETFL, lSocketFlag | O_NONBLOCK),使得SSL_connect成为非阻塞函数,调用后会立即返回。
调用后连接未必建立成功,大概率会返回WOLFSSL_FATAL_ERROR。(只有C&S相邻很近时能直接返回SSL_SUCCESS)。此时使用wolfSSL_get_error函数获取错误码,实测会获取到SSL_ERROR_WANT_READ,类似于"正在连接中"。这时再使用select机制监听socket是否可写,若在select超时时间内触发可写,则我们可以通过调用getsockopt来得到套接口上待处理的错误(SO_ERROR),如果连接建立成功,这个错误值将是0;如果建立连接时遇到错误,则这个值是连接错误所对应的errno值(比如:ECONNREFUSED,ETIMEDOUT等)。反之则认为在人为设定的时间内超时,按连接失败处理。
另,socket默认阻塞模式下connect也会存在阻塞问题,出现过10s以上才返回成功的情况。常用解决方法和上述思路一致,区别是非阻塞下的socket大部分会先进入errno = EINPROGRESS(正在连接)状态。
*注意,在处理完connect后必须将socket再改回阻塞模式,否则后续的读写操作会出现系统错误[资源不可用]
【问题三:SSL_write返回值处理不当导致业务逻辑死循环】
当对方断开连接时,该函数执行后返回0,errno为 [connection closed by peer]。因此需考虑到返回0对应的错误处理,或者简单点把<=0都认为是写失败亦可,切勿在"leftLen -= sendLen配合循环写"的设计中造成死循环。
另外,socket相关很多读写接口在返回值为0时都表示连接断开,请自行查阅学习。
【问题四:SSL_read卡死】复现条件不明确,应该还是和网络环境有关。
【解决方法】给socket设置接收超时时间,对在其基础上创建的ssl连接同样有效。setsockopt(hHandle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_out,  sizeof(tv_out))

此类问题在简单网络环境情况下从未出现,因此考验的是开发人员网络编程技术的实战水平。若功能仅基本跑通,不能满足实际工程需要,对于产品质量、客户体验、维护成本上的负面影响是巨大的。

另,wolfSSL_get_error(pSsl, -1) 函数的第二个参数为什么常填-1?
该函数用于获取SSL错误码,按正常要求应该填返回值(比如刚才执行了ret = SSL_connect)。但是源码中该入参只用于校验是否存在错误,如果没有则返回WOLFSSL_ERROR_NONE。所以只要我们业务上确保有错需要获取错误码,该入参就可以填-1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值