讀:
在阻塞條件下,如果沒有發現數據在網絡緩沖中會一直等待,當發現有數據的時候會把數據讀到用戶指定的緩沖區。但是如果這個時候讀到的數據量比較少,比參數中指定的長度要小,
read並不會一直等待下去,而是立刻返回。read的原則是數據在不超過指定的長度的時候有多少讀多少,沒有數據就會一直等待。所以一般情況下我們讀取數據都需要采用循環讀的方式讀取數據,
一次read完畢不能保證讀到我們需要長度的數據,read完一次需要判斷讀到的數據長度再決定是否還需要再次讀取。
在非阻塞的情況下,read的行為是如果發現沒有數據就直接返回,如果發現有數據那么也是采用有多少讀多少的進行處理.對於讀而言,阻塞和非阻塞的區別在於沒有數據到達的時候是否立刻返回。
寫:
在阻塞的情況,是會一直等待直到write完全部的數據再返回。 非阻塞寫的情況,是采用可以寫多少就寫多少的策略。
io多路復用
# 在並發高的情況下,連接活躍度不是很高, epoll比select
# 並發性不高,同時連接很活躍, select比epoll好
#通過非阻塞io實現http請求 import socket from urllib.parse import urlparse #使用非阻塞io完成http請求 def get_url(url): #通過socket請求html url = urlparse(url) host = url.netloc path = url.path if path == "": path = "/" #建立socket連接 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.setblocking(False) try: client.connect((host, 80)) #阻塞不會消耗cpu except BlockingIOError as e: pass #不停的詢問連接是否建立好, 需要while循環不停的去檢查狀態 #做計算任務或者再次發起其他的連接請求 while True: try: client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8")) break except OSError as e: pass data = b"" while True: try: d = client.recv(1024) except BlockingIOError as e: continue if d: data += d else: break data = data.decode("utf8") html_data = data.split("\r\n\r\n")[1] print(html_data) client.close() if __name__ == "__main__": get_url("http://www.baidu.com")