1. select函式
#include
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
void fd_clr(int fd, fd_set* set);
int fd_isset(int fd, fd_set* set);
void fd_set(int fd, fd_set* set);
void fd_zero(fd_set* set);
參1:最大的檔案描述符 + 1
2. poll函式
#include
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
struct pollfd epoll_data_t;
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
events: 陣列,傳出引數。
maxevents:告知核心這個events有多大
timeout: 超時時間, -1 --> 阻塞; 0 --> 立即返回,非阻塞;> 0 --> 指定毫秒
返回值:成功返回有多少檔案描述符就緒,時間到時返回0,出錯返回-1.
#ifndef _multithread_epoll_test_h
#define _multithread_epoll_test_h
class epollserver
;#endif
#include #include #include #include #include #include #include #include #include #include #include #include "multithread_epoll_test.h"
epollserver::epollserver()
epollserver::~epollserver()
void epollserver::onrun()
for (int i = 0; i < ret; ++i)}}
}void epollserver::accept()
char buf[bufsiz];
printf("new client joined, port = %d, ip = %s\n",
ntohs(clientaddr.sin_port),
inet_ntop(af_inet, (const void*)&clientaddr.sin_addr.s_addr, buf, bufsiz));
struct epoll_event evt;
bzero(&evt, sizeof(evt));
evt.events = epollin;
evt.data.fd = clientfd;
epoll_ctl(m_epfd, epoll_ctl_add, clientfd, &evt);
}void epollserver::handlemsg(int clientfd)
else if (ret < 0)
else
}
4. 水平觸發epoll lt/ 邊沿觸發 epoll et
水平觸發:evt.events = epollin; --> 預設
邊沿觸發: evt.events =epollin | epollet;
5. 非阻塞i/o: fcntl函式與open函式(open不適用socket)
int flag = fcntl(cfd, f_getfl);
flag |= o_nonblock;
fcntl(cfd, f_setfl, flag);
非阻塞模式read時需要while迴圈,從而達到減少epoll_wait的呼叫。
邊沿觸發 + 非阻塞模式是最高效的方式。邊沿觸發在一次性讀不完資料時可以減少epoll_wait的呼叫。
epoll工作在et模式的時候,必須使用非阻塞套介面,以避免由於乙個檔案控制代碼的阻塞讀/阻塞寫操作把處理多個檔案描述符的任務餓死。最好以下面的方式呼叫et模式的epoll介面,在後面會介紹避免可能的缺陷。
i 基於非阻塞檔案控制代碼
ii 只有當read(2)或者write(2)返回eagain時才需要掛起,等待。但這並不是說每次read()時都需要迴圈讀,直到讀到產生乙個eagain才認為此次事件處理完成,當read()返回的讀到的資料長度小於請求的資料長度時,就可以確定此時緩衝中已沒有資料了,也就可以認為此事讀事件已處理完成。
所以判斷et模式迴圈讀取是否讀取完成的方法:當讀取資料長度小於設定的長度或者返回-1並且errno為eagain或ewouldblock時。
當讀取數量==請求數量時,繼續讀取下一輪(buffer太小)。
while (1)
close(sockfd);
break;
}else if (ret == 0)
else
printf("收到訊息:%s, 共%d個位元組\n", buffer, ret);
}printf("帶迴圈的et處理結束!!!\n");
網路程式設計之 多路IO轉接 select模型
select模型 優點 可跨平台 實現多路復用 避免了頻繁建立多程序 多執行緒處理連線產生的開銷,提高了連線處理效率 缺點 最多監聽1024個檔案描述符 事件處理時需要依次遍歷,帶來不必要的開銷 select函式原型 nfds 最大描述符加1 readfds 輸入輸出引數 返回讀事件檔案描述符集合 ...
網路程式設計之 多路IO轉接 select模型改進
select模型中在處理監聽事件時需要對檔案描述符依次遍歷,此處可以稍作改進,避免不必要的遍歷。改進思路 定義乙個fd setsize大小的陣列,用於儲存有效連線 定義乙個下標變數用於記錄儲存連線陣列中的有效連線最大下標,供遍歷作為上限值使用 int maxc 1 int client fd set...
網路程式設計之沒有io多路復用
網路程式設計www.baidu.com 網域名稱 每個網域名稱都有對應的ip 202.108.22.5 tcp 有連線的,可靠的,一定可以保證訊息可以傳達給對方,有三次握手 udp 沒有連線到 不可靠的 不能保證訊息一定能夠傳達給對方,不存在三次握手 利用套接字進行通訊 伺服器有兩個套接字 乙個叫監...