在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。
epoll 是當今 linux 系統採用的方式,一般伺服器都是用 epoll 來實現的。epoll 是一種方案,這種方案不使用多程序多執行緒多協程,而是使用單程序單執行緒來實現高併發。那我們之前寫的單程序單執行緒非阻塞的程式和epoll有什麼區別呢?
我們之前寫的程式是建乙個列表儲存套接字,然後遍歷,這種方式叫輪詢。明顯比較慢。
epoll :是誰收到誰舉手,這種方式叫事件通知。
藍色表示共享記憶體,綠色表示儲存列表,黃色套接字,白色監聽套接字。
程式來實現:
import socket
import re
import select
def service_client(new_client_sock,requst):
'''為這個客戶服務'''
# 轉為列表
requst_lines = requst.splitlines()
# 尋找檔名 get /index.html http/1.1
# 開頭有:get post put del 不一定是get 所以應該不能用get匹配。
file_name = ''
ret = re.match(r'[^/]+(/[^ ]*)',requst_lines[0])
if ret:
file_name = ret.group(1)
if file_name == '/ ':
file_name = '/index.html'
# 2.3 準備body,且這裡準備的body不能和之前的字串一樣,直接相加,而是要單獨傳送。
# 找到相對應的.html檔案
# 2.返回資料給瀏覽器,http 格式
# 2.4 傳送資料給瀏覽器
new_client_sock.send((response))
# 3.長連線不能使用close關閉套接字,那麼我們怎麼知道資料已經發完了呢?
# 在 header 中加入傳送資料的長度 content-length:
# new_client_sock.close()
def main():
'''用來完成整體的控制'''
# 1.建立套接字
tcp_socket = socket.socket(socket.af_inet, socket.sock_stream)
# 2.繫結
tcp_socket.bind(('', 7890))
# 3.變為監聽套接字
tcp_socket.listen(128)
tcp_socket.setblocking(false) # 將套接字變為非堵塞
# 建立乙個epoll物件
epl = select.epoll()
# 將監聽套接字對應的 fd 註冊到 epoll中。
epl.register(tcp_socket.fileno(), select.epollin)
fd_event_dict = dict()
while true:
fd_event_list = epl.poll() # 缺省會堵塞,直到os 檢測到資料到來,通過事件通知的方式告訴這個程式,此時才會解堵塞
# [(fd, event),(套接字對應的文字描述符,這個檔案描述符到底是什麼事件,例如:可以呼叫recv接收等)]
for fd,enent in fd_event_list:
# 4.等待客戶端的鏈結
if fd == tcp_socket.fileno():
new_client_sock, client_addr = tcp_socket.accept()
epl.register(new_client_sock.fileno(), select.epollin)
fd_event_dict[new_client_sock.fileno()] = new_client_sock
elif event == select.epollin:
# 判斷已經鏈結的客戶端是否有資料傳送過來
recv_data = fd_event_dict[fd].recv(1024).decode('utf-8')
if recv_data:
service_client(fd_event_dict[fd],recv_data)
else:
fd_event_dict[fd].close()
epl.unregister(fd)
del fd_event_dict[fd]
# 4.關閉監聽套接字
tcp_socket.close()
if __name__ == '__main__':
main()
web伺服器 簡單web伺服器實現
三次握手 一般情況下是瀏覽器先傳送請求資料,c s ack 應答 三次握手成功後,才開始進行通訊資料的收發。四次揮手 一般情況下是客戶端先關閉,給瀏覽器傳送關閉資訊。如果瀏覽器傳送了關閉資訊,但是伺服器沒有回過去,較慢 那麼瀏覽器一直發是不是就會有問題?所以會等待 2msl的時間。一般為2 5分鐘。...
Web伺服器 併發伺服器 長連線(3 4 4)
每次new socket都被強制關閉,造成短連線 所提不要關閉套接字 但是不關閉的話,瀏覽器不知道發完沒有啊 此時用到header的屬性content length 將http body的長度裝到返回頭,送出給瀏覽器 當瀏覽器獲取完資料了之後,就不會再載入了 設定非堵塞 tcp sever sock...
Web伺服器 併發伺服器 Epoll(3 4 5)
epoll是一種解決方案,nginx就是用的這個 中心思想 不要再使用多程序,多執行緒了,使用單程序,單執行緒去實現併發 在上面部落格實現的 中使用過的輪詢去檢視套接字有沒有資料,而epoll是主動通知 當使用多程序的時候,是複製乙份資源去檢視,epoll不用複製,直接來 優勢 1.共享記憶體 2....