linux – socket selectv on select()ed socket使用etimedout失
我正在编写一个服务器 – 客户端程序,其中包含以下代码片段以接收数据.
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将为您提供缓冲区中的内容(最多为您在函数调用中指定的最大值),阻塞或失败.这三件事之一,没有别的,永远.一旦失败,你已经拥有了失败之前可用的所有东西(你的结尾没什么可读的),现在连接已经消失,即套接字不再可用了.您唯一能做的就是创建一个新的套接字并建立一个新的连接,然后再试一次. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |