加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – socket selectv on select()ed socket使用etimedout失

发布时间:2020-12-14 00:05:09 所属栏目:Linux 来源:网络整理
导读:我正在编写一个服务器 – 客户端程序,其中包含以下代码片段以接收数据. ret_l = select(readfds+1,readfds,NULL,NULL); if(ret_l != -1) { if(FD_ISSET(myfd,readfds)) { ret_l = recv(myfd,buf,size_of_buf_array,0); if(ret_l == -1) return ; } } 据我所
我正在编写一个服务器 – 客户端程序,其中包含以下代码片段以接收数据.

ret_l = select(readfds+1,&readfds,NULL,NULL);
    if(ret_l != -1)
    {
        if(FD_ISSET(myfd,&readfds))
        {
             ret_l = recv(myfd,buf,size_of_buf_array,0);
             if(ret_l == -1)
                 return ;
         }
    }

据我所知,select()ed文件描述符上的recv应该没有失败地接收数据.但是我的代码中的recv因错误ETIMEDOUT而失败.有人请告诉我为什么会这样.还请告诉我一些解决方法,即使在ETIMEDOUT之后也能完全接收数据.

解决方法

看到ETIMEDOUT有三个可能的原因:

>连接在recv内部超时,这种情况甚至不太可能发生一次(但肯定不会发生几次).
>您没有检查连接是否成功,并且连接从未成功建立(防火墙可能正在丢弃连接尝试?).这是可能的原因.
>你的套接字实现被破坏了,这是不太可能的.

select不生成ETIMEDOUT,只有connect和recv可能.尽管选择可以在极少数情况下报告无法接收时的准备情况(较旧的Linux内核,这可能已被修复),但在这种情况下唯一可能发生的是recv阻塞.

recv可能会产生这个错误,但是一旦建立连接就不会超时 – 如果你没有拉电缆,或者如nos所指出的那样,NAT网关可能会在几分钟没有做任何事情后超时.如果可以建立连接,则有一条路由,有人正在另一端进行侦听,因此通常没有超时的常规原因(当然,这是可能的,不太可能一直发生).如果连接由于某种原因(无论阻塞)真的超时,这个错误当然最终会发生,但如果有的话,这是一个非常特殊的条件,而不是常规条件.

连接失败是一种您可能会想到的条件,由于许多原因(无法访问,防火墙,服务器进程未运行等),并且每次尝试时都会经常发生这种情况,只要导致这种情况它坚持下去.

至于在ETIMEDOUT之后完全接收数据的变通方法,则没有. read将为您提供缓冲区中的内容(最多为您在函数调用中指定的最大值),阻塞或失败.这三件事之一,没有别的,永远.一旦失败,你已经拥有了失败之前可用的所有东西(你的结尾没什么可读的),现在连接已经消失,即套接字不再可用了.您唯一能做的就是创建一个新的套接字并建立一个新的连接,然后再试一次.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读