新聞中心
網(wǎng)絡(luò)編程中阻塞和非阻塞socket的區(qū)別?
阻塞:一般的I/O操作可以在新建的流中運(yùn)用.在服務(wù)器回應(yīng)前它等待客戶端發(fā)送一個(gè)空白的行.當(dāng)會話結(jié)束時(shí),服務(wù)器關(guān)閉流和客戶端socket.如果在隊(duì)列中沒有請示將會出現(xiàn)什么情況呢?那個(gè)方法將會等待一個(gè)的到來.這個(gè)行為叫阻塞.accept()方法將會阻塞服務(wù)器線程直到一個(gè)呼叫到來.當(dāng)5個(gè)連接處理完閉之后,服務(wù)器退出.任何的在隊(duì)列中的呼叫將會被取消.

非阻塞:非阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),不管是否執(zhí)行成功,都立即返回。比如調(diào)用recv()函數(shù)讀取網(wǎng)絡(luò)緩沖區(qū)中數(shù)據(jù),不管是否讀到數(shù)據(jù)都立即返回,而不會一直掛在此函數(shù)調(diào)用上。在實(shí)際Windows網(wǎng)絡(luò)通信軟件開發(fā)中,異步非阻塞套接字是用的最多的。平常所說的C/S(客戶端/服務(wù)器)結(jié)構(gòu)的軟件就是異步非阻塞模式的
為什么我的socket的read方法沒有阻塞,直接?
一、你調(diào)用read的時(shí)候,實(shí)際上調(diào)用的是socketchannel的read方法,而你設(shè)置的阻塞模式是ServerSocketChannel的模式,所以調(diào)用read時(shí)依然會采用默認(rèn)的阻塞方式,如果你希望用非阻塞的方式,只要設(shè)置一下socketchannel的阻塞模式就OK了。
二、默認(rèn)情況下,read的方法是阻塞模式的,所以沒有辦法設(shè)置他的超時(shí)時(shí)間,如果客戶端異常退出,當(dāng)前的連接將永遠(yuǎn)等待下去,如果你修改成非阻塞模式就沒有這個(gè)問題了,非阻塞模式你可以判斷read返回值,如果超過N時(shí)間返回值一直都是0,就把當(dāng)前的連接關(guān)閉。
三、我并沒有這樣混合用過,還沒遇到過這樣的問題,我猜想有可能是跟關(guān)閉的socketchannel、socket等等有關(guān)吧,可能關(guān)閉socket和關(guān)閉channel有些區(qū)別,我也不確定,反正建議你,想要NIO就用NIO,要是想要serversocket和scoket,那就只用這兩個(gè),盡量不要混合使用。希望對你有幫助。
recv是阻塞還是非阻塞的?
socket分為阻塞和非阻塞兩種,可以通過setsockopt,或者更簡單的setblocking, settimeout設(shè)置。
阻塞式的socket的recv服從這樣的規(guī)則:當(dāng)緩沖區(qū)內(nèi)有數(shù)據(jù)時(shí),立即返回所有的數(shù)據(jù);當(dāng)緩沖區(qū)內(nèi)無數(shù)據(jù)時(shí),阻塞直到緩沖區(qū)中有數(shù)據(jù)。
非阻塞式的socket的recv服從的規(guī)則則是:當(dāng)緩沖區(qū)內(nèi)有數(shù)據(jù)時(shí),立即返回所有的數(shù)據(jù);當(dāng)緩沖區(qū)內(nèi)無數(shù)據(jù)時(shí),產(chǎn)生EAGAIN的錯(cuò)誤并返回(在Python中會拋出一個(gè)異常)。
兩種情況都不會返回空字符串,返回空數(shù)據(jù)的結(jié)果是對方關(guān)閉了連接之后才會出現(xiàn)的。由于TCP的socket是一個(gè)流,因此是不存在“讀完了對方發(fā)送來的數(shù)據(jù)”這件事的。
你必須要每次讀到數(shù)據(jù)之后,根據(jù)數(shù)據(jù)本身來判斷當(dāng)前需要等待的數(shù)據(jù)是否已經(jīng)全部收到,來判斷是否進(jìn)行下一個(gè)recv。
可以看一下hiredis庫的接口設(shè)計(jì),hiredis中的Reader有兩個(gè)接口,分別是feed和gets,feed每次送入一部分?jǐn)?shù)據(jù),不需要保證是正確分片的;gets則返回已經(jīng)得到的完整的結(jié)果,如果返回False,表示已經(jīng)沒有新的結(jié)果?;旧纤械腡CP的socket編程都是遵循這樣的方法:讀入新數(shù)據(jù);判斷有沒有完整的新消息;處理新消息,或者等待更多數(shù)據(jù)。
到此,以上就是小編對于linux 非阻塞io的問題就介紹到這了,希望這3點(diǎn)解答對大家有用。
本文題目:Linux服務(wù)器如何處理非阻塞Socket?
當(dāng)前網(wǎng)址:http://www.5511xx.com/article/dhpopcg.html


咨詢
建站咨詢
