socket分为阻塞和非阻塞两种,可以通过setsockopt,或者更简单的setblocking, settimeout设置。
成都创新互联是一家集网站建设,罗庄企业网站建设,罗庄品牌网站建设,网站定制,罗庄网站建设报价,网络营销,网络优化,罗庄网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
阻塞式的socket的recv服从这样的规则:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,阻塞直到缓冲区中有数据。
非阻塞式的socket的recv服从的规则则是:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,产生EAGAIN的错误并返回(在Python中会抛出一个异常)。
两种情况都不会返回空字符串,返回空数据的结果是对方关闭了连接之后才会出现的。由于TCP的socket是一个流,因此是不存在“读完了对方发送来的数据”这件事的。
你必须要每次读到数据之后,根据数据本身来判断当前需要等待的数据是否已经全部收到,来判断是否进行下一个recv。
可以看一下hiredis库的接口设计,hiredis中的Reader有两个接口,分别是feed和gets,feed每次送入一部分数据,不需要保证是正确分片的;gets则返回已经得到的完整的结果,如果返回False,表示已经没有新的结果。基本上所有的TCP的socket编程都是遵循这样的方法:读入新数据;判断有没有完整的新消息;处理新消息,或者等待更多数据。
阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket.如果在队列中没有请示将会出现什么情况呢?那个方法将会等待一个的到来.这个行为叫阻塞.accept()方法将会阻塞服务器线程直到一个呼叫到来.当5个连接处理完闭之后,服务器退出.任何的在队列中的呼叫将会被取消.
非阻塞:非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的
由于socket是以数据流的形式发送数据,接收方不知道对方一次性发送了多少数据,也能保证对方一次性发送的数据能在同一刻接收到,所以Receive方法是这么工作的:
接受一个byye[]类型的参数作为缓冲区,在经过一定的时间后把接收到的数据填充到这个缓冲区里面,并且返回实际接收到数据的长度,这个实际接收到的数据长度有可能为0(没有接收到数据)、大于0小于缓冲区的长度(接收到数据,但是没有我们预期的多)、等于缓冲区的长度(说明接收到的数据大于等于我们预期的长度)。
每次接收缓冲区都用同一个byte[]byteMessage,并且你没有检查接收到的数据长度,所以第一次你接收到的数据是123456,第二次你只接收到了8,但是缓冲区里面还有23456,所以加起来就是823456了。
socket接收缓冲区的大小有讲究,设置大了接收起来慢,因为它要等尽可能多的数据接收到了再返回;设置小了需要重复多次调用接收方法才能把数据接收完,socket有个属性,标识了系统默认的接收缓冲区大小,可以参考这个!
还有就是用recv读取,但是由于不知道缓存里有多少数据,如果是阻塞模式,到最后必然等到超时才知道数据已经读取完毕,这是个问题。
另一个是用fgetc,通过返回判断是否是feof:
whlie(1){a=fgetc(f);if(feof(f))break;//…
b=fgetc(f);if(feof(f))break;//… } 当然,我不知道读取完毕后最后一次调用fgetc会不会堵塞,需要测试。
到此,以上就是小编对于Windows非阻塞send返回值的问题就介绍到这了,希望这3点解答对大家有用。
新闻标题:recv是阻塞还是非阻塞的?windows非阻塞recv
网页链接:http://www.shufengxianlan.com/qtweb/news1/397951.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联