Linux服务器如何处理非阻塞Socket?

网络编程中阻塞和非阻塞socket的区别?

阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket.如果在队列中没有请示将会出现什么情况呢?那个方法将会等待一个的到来.这个行为叫阻塞.accept()方法将会阻塞服务器线程直到一个呼叫到来.当5个连接处理完闭之后,服务器退出.任何的在队列中的呼叫将会被取消.

非阻塞:非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的

为什么我的socket的read方法没有阻塞,直接?

一、你调用read的时候,实际上调用的是socketchannel的read方法,而你设置的阻塞模式是ServerSocketChannel的模式,所以调用read时依然会采用默认的阻塞方式,如果你希望用非阻塞的方式,只要设置一下socketchannel的阻塞模式就OK了。

二、默认情况下,read的方法是阻塞模式的,所以没有办法设置他的超时时间,如果客户端异常退出,当前的连接将永远等待下去,如果你修改成非阻塞模式就没有这个问题了,非阻塞模式你可以判断read返回值,如果超过N时间返回值一直都是0,就把当前的连接关闭。

三、我并没有这样混合用过,还没遇到过这样的问题,我猜想有可能是跟关闭的socketchannel、socket等等有关吧,可能关闭socket和关闭channel有些区别,我也不确定,反正建议你,想要NIO就用NIO,要是想要serversocket和scoket,那就只用这两个,尽量不要混合使用。希望对你有帮助。

recv是阻塞还是非阻塞的?

socket分为阻塞和非阻塞两种,可以通过setsockopt,或者更简单的setblocking, settimeout设置。

阻塞式的socket的recv服从这样的规则:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,阻塞直到缓冲区中有数据。

非阻塞式的socket的recv服从的规则则是:当缓冲区内有数据时,立即返回所有的数据;当缓冲区内无数据时,产生EAGAIN的错误并返回(在Python中会抛出一个异常)。

两种情况都不会返回空字符串,返回空数据的结果是对方关闭了连接之后才会出现的。由于TCP的socket是一个流,因此是不存在“读完了对方发送来的数据”这件事的。

你必须要每次读到数据之后,根据数据本身来判断当前需要等待的数据是否已经全部收到,来判断是否进行下一个recv。

可以看一下hiredis库的接口设计,hiredis中的Reader有两个接口,分别是feed和gets,feed每次送入一部分数据,不需要保证是正确分片的;gets则返回已经得到的完整的结果,如果返回False,表示已经没有新的结果。基本上所有的TCP的socket编程都是遵循这样的方法:读入新数据;判断有没有完整的新消息;处理新消息,或者等待更多数据。

到此,以上就是小编对于linux 非阻塞io的问题就介绍到这了,希望这3点解答对大家有用。

分享名称:Linux服务器如何处理非阻塞Socket?
文章路径:http://www.shufengxianlan.com/qtweb/news5/477905.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联