epoll是常用的socket通訊方式,相比於select和poll來說,效率提公升了不止一點半點
其一:select中socket描述符(檔案描述符)集的資料結構為陣列,poll的檔案描述符集資料結構為鍊錶,無論陣列還是鍊錶,它們都是線性結構,當遍歷時,也只能線性遍歷;而epoll檔案描述符集採用的紅黑樹(平衡二叉樹的乙個變體)的資料結構,紅黑樹的遍歷則相比於線性遍歷,效率要高很多。
其二:select和poll對檔案描述符集先要拷貝到核心區,核心修改後再拷貝至使用者區,要經過2次拷貝;而epoll底層用的是共享記憶體的方式,即核心區與使用者區共享一片記憶體,無需拷貝,也就大大提高了效率。
#include // 建立一棵紅黑樹
int epoll_create(int size);
引數:
size: 沒意義, 隨便寫個數就行(早期epoll資料結構為hash表,需要指定表長,但後面改為紅黑樹後其實樹節點個數就沒有什麼意義了)
返回值;
>0: 檔案描述符, 操作epoll樹的根節點
epoll檢測的事件:
- epollin
- epolout
- epollerr
// 對epoll樹進行管理: 新增節點, 刪除節點, 修改已有的節點屬性
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
引數:- epfd: epoll_create的返回值, 通過這個值就可以找到紅黑樹
- op: 要進行什麼樣的操作
epoll_ctl_add: 註冊新節點, 新增到紅黑樹上
epoll_ctl_mod: 修改檢測的檔案描述符的屬性
epoll_ctl_del: 從紅黑樹上刪除節點
- fd: 要檢測的檔案描述符的值
- event: 檢測檔案描述符的什麼事件
// 檢測函式
struct epoll_event events[1000];
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
引數:- epfd: epoll_create的返回值(這棵紅黑樹的根節點), 通過這個值就可以找到紅黑樹
- events: 傳出引數, 儲存了發生變化的檔案描述符的資訊(陣列形式)
- maxevents: 第二個引數結構體陣列的大小
- timeout: 阻塞時間
- 0: 不阻塞
- -1: 一直阻塞, 知道檢測的fd有狀態變化, 解除阻塞
- >0: 阻塞的時長(毫秒)
返回值:
- 成功: 有多少個檔案描述符狀態發生了變化 > 0
- 失敗: -1
下面直接上**吧
server.c
#include #include #include #include #include #include #include int main()
// 2. 繫結 ip, port
struct sockaddr_in addr;
addr.sin_port = htons(1234);
addr.sin_family = af_inet;
addr.sin_addr.s_addr = inaddr_any;
int ret = bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
if(ret == -1)
// 3. 監聽
ret = listen(lfd, 100);
if(ret == -1)
// 4. 建立epoll樹
int epfd = epoll_create(1000);//1000並沒有什麼意義
if(epfd == -1)
//5、將用於監聽的lfd掛的epoll樹上(紅黑樹)
struct epoll_event ev;//這個結構體記錄了檢測什麼檔案描述符的什麼事件
ev.events = epollin;
ev.data.fd = lfd;
epoll_ctl(epfd, epoll_ctl_add, lfd, &ev);//ev裡面記錄了檢測lfd的什麼事件
// 迴圈檢測 委託核心去處理
struct epoll_event events[1024];//當核心檢測到事件到來時會將事件寫到這個結構體陣列裡
while(1)
else
else}}
}}
close(lfd);
return 0;
}
client.c
#include #include #include #include #include #include int main()
printf("connect success!!!\n");
//讀取伺服器傳回的資料
char buffer[100];
//recv(sock, buffer, sizeof(buffer),0);
//printf("message form server: %s\n", buffer);
while(1)
//關閉套接字
close(sock);
return 0;
}
php簡單實現socket通訊
socket通訊的原理在這裡就不說了,它的用途還是比較廣泛的,我們可以使用 socket 來做乙個 api介面出來,也可以使用 socket 來實現兩個程式之間的通訊,我們來研究一下在 php開發 中如何實現socket通訊。由於socket服務端的 要監聽埠,等待接收請求,所以 php在做 soc...
Socket簡單實現ssh筆記
socket本質上就是在2臺網路互通的電腦之間,架設乙個通道,兩台電腦通過這個通道來實現資料的互相傳遞。我們知道網路 通訊 都 是基於 ip port 方能定位到目標的具體機器上的具體服務,作業系統有0 65535個埠,每個埠都可以獨立對外提供服務,如果 把乙個公司比做一台電腦 那公司的總機號碼就相...
Epoll 模型實現
while true else if m events i data.fd m listen sock fd 如果新監測到乙個socket使用者連線到了繫結的socket埠,建立新的連線。else if m events i events epollin 如果是已經連線的使用者,並且收到資料,那麼進...