Linux網路程式設計(5)epoll實現IO多路轉接

2021-09-25 08:25:12 字數 4082 閱讀 8229

epoll相關函式介紹

epoll大致實現思路

假設現在存有乙個檔案描述符表,該表中存有對應的用於監聽連線請求的檔案描述符lfd,則建立乙個樹狀結構,該樹狀結構根節點對應著檔案描述符表的3號位置(0.1.2位置為系統占用位),左節點為第4號位置,依次類推,直到所有節點填充完畢,在統一對該樹狀結構進行管理。

1.該樹結構為紅黑二叉樹

2.掛載在樹上的結構型別為結構體型別struct epoll_event

關於epoll的三個主要函式

1.int epoll_creae(int size);

該函式生成乙個epoll專用的檔案描述符,在樹狀結構中對應著根節點

size: epoll上能關注的最大描述符數,用於控制某個epoll檔案描述符事件,可以註冊、修改、刪除,當實際空間超過該宣告時候,系統將自動拓展其空間

2.檔案描述符控制函式

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

用於控制某個epoll檔案描述符事件,可以注

冊、修改、刪除

函式引數

epfd:epoll_create生成的epoll專用描述符

op:對應操作巨集

epoll_ctl_add – 註冊

epoll_ctl_mod – 修改

epoll_ctl_del – 刪除

fd: 關聯的檔案描述符

event: 告訴核心要監聽什麼事件

3.等待io事件發生 - 可以設定阻塞的函式

int epoll_wait(

int epfd;

struct epoll_event*events //陣列

int maxevents

int timeout

);對應select和poll函式

函式引數:

epfd:要檢測的控制代碼

events:用於回傳待處理事件的陣列

maxevents:告訴核心這個events的大小

timeout:為超時時間

-1:永久阻塞

0:立即返回

簡單的epoll模型**

#include #include #include #include #include #include #include #include #include int main(int argc, const char* ar**)

struct sockaddr_in serv_addr;

socklen_t serv_len = sizeof(serv_addr);

int port = atoi(ar**[1]);

// 建立套接字

int lfd = socket(af_inet, sock_stream, 0);

// 初始化伺服器 sockaddr_in

memset(&serv_addr, 0, serv_len);

serv_addr.sin_family = af_inet; // 位址族

serv_addr.sin_addr.s_addr = htonl(inaddr_any); // 監聽本機所有的ip

serv_addr.sin_port = htons(port); // 設定埠

// 繫結ip和埠

bind(lfd, (struct sockaddr*)&serv_addr, serv_len);

// 設定同時監聽的最大個數

listen(lfd, 36);

printf("start accept ......\n");

struct sockaddr_in client_addr;

socklen_t cli_len = sizeof(client_addr);

// 建立epoll樹根節點

int epfd = epoll_create(2000);

// 初始化epoll樹

struct epoll_event ev;

ev.events = epollin;

ev.data.fd = lfd;

epoll_ctl(epfd, epoll_ctl_add, lfd, &ev);

struct epoll_event all[2000];

while(1)

參考**

#include #include #include #include #include #include #include #include #include #include #include int main(int argc, const char* ar**)

struct sockaddr_in serv_addr;

socklen_t serv_len = sizeof(serv_addr);

int port = atoi(ar**[1]);

// 建立套接字

int lfd = socket(af_inet, sock_stream, 0);

// 初始化伺服器 sockaddr_in

memset(&serv_addr, 0, serv_len);

serv_addr.sin_family = af_inet; // 位址族

serv_addr.sin_addr.s_addr = htonl(inaddr_any); // 監聽本機所有的ip

serv_addr.sin_port = htons(port); // 設定埠

// 繫結ip和埠

bind(lfd, (struct sockaddr*)&serv_addr, serv_len);

// 設定同時監聽的最大個數

listen(lfd, 36);

printf("start accept ......\n");

struct sockaddr_in client_addr;

socklen_t cli_len = sizeof(client_addr);

// 建立epoll樹根節點

int epfd = epoll_create(2000);

// 初始化epoll樹

struct epoll_event ev;

// 設定邊沿觸發

ev.events = epollin;

ev.data.fd = lfd;

epoll_ctl(epfd, epoll_ctl_add, lfd, &ev);

struct epoll_event all[2000];

while(1)

if(len == 0)

close(fd);

}else if(len == -1)

else

}#if 0

if(len == -1)

else if(len == 0)

close(fd);

}else

#endif}}

}close(lfd);

return 0;

}

*如何讓檔案描述符突破1024的限制

1.在程式中

select 突破不了,需要編譯核心,通過陣列實現,

poll和epoll可以突破1024的限制

poll內部的鍊錶

epoll紅黑樹

2.在系統中

檢視受計算機硬體限制的檔案描述符上線

cat /proc/sys/fs/file-max

並通過修改配置檔案調整其上限

vim /etc/security/limits.conf

新增如下資訊

* soft nofile 8000

* hard nofile 8000

linux網路程式設計之 epoll

include include include include include include include include include include using namespace std define maxline 5 define open max 100 define listen...

python 網路程式設計 epoll的大坑

eopll 例項預設監聽 select.epollhup 一般只需要監聽select.epollin事件就行了 在另一方關閉連線時會傳送乙個空串,select.epollin 會捕捉這個空串事件,如果不對它處理的話這個事件會一直響應,需要手動關閉 connection.close 一般將所有連線的描...

實驗5 linux網路程式設計

完成基於tcp的客戶端和伺服器程式編寫,要求伺服器採用迴圈方式處理客戶端的資料。server.c include include include include include include include include define server port 5012 define serv i...