c 網路程式設計(1)

2021-08-01 18:48:54 字數 2027 閱讀 7525

一、epoll網路程式設計

select()和poll() io多路復用模型

select的缺點:

相比select模型,poll使用鍊錶儲存檔案描述符,因此沒有了監視檔案數量的限制,但其他三個缺點依然存在。

在linux的網路程式設計中,很長的時間都在使用select來做事件觸發。在linux新的核心中,有了一種替換它的機制,就是epoll。

epoll io多路復用模型實現機制

由於epoll的實現機制與select/poll機制完全不同,上面所說的 select的缺點在epoll上不復存在。

設想一下如下場景:有100萬個客戶端同時與乙個伺服器程序保持著tcp連線。而每一時刻,通常只有幾百上千個tcp連線是活躍的(事實上大部分場景都是這種情況)。如何實現這樣的高併發?

在select/poll時代,伺服器程序每次都把這100萬個連線告訴作業系統(從使用者態複製控制代碼資料結構到核心態),讓作業系統核心去查詢這些套接字上是否有事件發生,輪詢完後,再將控制代碼資料複製到使用者態,讓伺服器應用程式輪詢處理已發生的網路事件,這一過程資源消耗較大,因此,select/poll一般只能處理幾千的併發連線。

epoll的設計和實現與select完全不同。epoll通過在linux核心中申請乙個簡易的檔案系統(檔案系統一般用什麼資料結構實現?b+樹)。把原先的select/poll呼叫分成了3個部分:

1)呼叫epoll_create()建立乙個epoll物件(在epoll檔案系統中為這個控制代碼物件分配資源)

2)呼叫epoll_ctl向epoll物件中新增這100萬個連線的套接字

3)呼叫epoll_wait收集發生的事件的連線

如此一來,要實現上面說是的場景,只需要在程序啟動時建立乙個epoll物件,然後在需要的時候向這個epoll物件中新增或者刪除連線。同時,epoll_wait的效率也非常高,因為呼叫epoll_wait時,並沒有一股腦的向作業系統複製這100萬個連線的控制代碼資料,核心也不需要去遍歷全部的連線。

二、epoll網路程式設計api學習

(1)int epoll_create(int size);

建立乙個epoll的控制代碼,size用來告訴核心這個監聽的數目一共有多大。這個引數不同於select()中的第乙個引數,給出最大監聽的fd+1的值。

需要注意的是,當建立好epoll控制代碼後,它就是會占用乙個fd值,在linux下如果檢視/proc/程序id/fd/,是能夠看到這個fd的,

所以在使用完epoll後,必須呼叫close()關閉,否則可能導致fd被耗盡。

自從linux 2.6.8開始,size引數被忽略,但是依然要大於0。

(2)int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll的事件註冊函式,它不同與select()是在監聽事件時告訴核心要監聽什麼型別的事件,而是在這裡先註冊要監聽的事件型別。

typedef

union epoll_data epoll_data_t;

struct epoll_event ;

events可以是以下幾個巨集的集合:

epollin :表示對應的檔案描述符可以讀(包括對端socket正常關閉);

epollout:表示對應的檔案描述符可以寫;

epollpri:表示對應的檔案描述符有緊急的資料可讀(這裡應該表示有帶外資料到來);

epollerr:表示對應的檔案描述符發生錯誤;

epollhup:表示對應的檔案描述符被結束通話;

epollet: 將epoll設為邊緣觸發(edge triggered)模式,這是相對於水平觸發(level triggered)來說的。

epolloneshot:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到epoll佇列裡

(3)int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

等待事件的產生,類似於select()呼叫。

c 網路程式設計學習筆記 1

前序 在多個os平台上開發和移植網路應用程式時,將面臨錯綜複雜的挑戰。這些複雜性的表現形式各異 網路協議不相容,在不同軟 硬體平台上具有不同的api和語義的元件庫,os本身的程序間通訊 ipc 機制和併發機制的侷限性造成的 偶發複雜性 直接針對os api程式設計會導致以下兩個問題 1 容易出錯。因...

網路程式設計 1

1.套接字位址結構 套接字程式設計需要指定套接字的位址作為引數,不同的協議族有不同的位址結構定義方式。這些位址結構通常以sockaddr 開頭,每乙個協議族有乙個唯一的字尾,例如對於乙太網,其結構名稱為sockaddr in。1.1 通用套接字位址結構 套接字位址結構 struct sockaddr...

網路程式設計 1

1.前言 公司要為別的公司提供伺服器防護,採用本地環迴,節點 的方法實現對伺服器真實ip進行隱藏。但是有乙個問題 我節點端要建立乙個埠接收對映資料和保活資料,採用固定埠的話,攻擊者很容易通過掃瞄埠來獲取我較多的節點,進行攻擊 2.解決 這裡採用的是通過節點ip來生成乙個隨機埠,客戶端和節點通過這個隨...