前面初始化監聽套接字listen_fd後,現在把它加入到epoll核心事件表當中。
// 初始化套接字開始監聽
int listen_fd = socket_bind_listen(conf.port);
// 設定為socket非阻塞
int rc = make_socket_non_blocking(listen_fd);
// 建立epoll並註冊監聽描述符,為events分配記憶體,最大可監聽事件為maxevents
int epoll_fd = tk_epoll_create(0);
tk_http_request_t* request = (tk_http_request_t*)malloc(sizeof(tk_http_request_t));//使用者自定義觸發事件request
tk_init_request_t(request, listen_fd, epoll_fd, conf.root);//初始化request
tk_epoll_add(epoll_fd, listen_fd, request, (epollin | epollet));//將監聽事件新增到epoll_fd中進行管理
埠的繫結用下面乙個函式。
int socket_bind_listen(int port)
// 設定伺服器ip和port,和監聽描述副繫結
struct sockaddr_in server_addr;
bzero((char*)&server_addr, sizeof(server_addr));//應該是置零操作
server_addr.sin_family = af_inet;
server_addr.sin_addr.s_addr = htonl(inaddr_any);
server_addr.sin_port = htons((unsigned short)port);
if(bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
return -1;
// 開始監聽,最大等待佇列長為listenq
if(listen(listen_fd, listenq) == -1)
return -1;
// 無效監聽描述符
if(listen_fd == -1)
return listen_fd;
}
呼叫close之後,不立即關閉,經歷一段time_wait階段,再對位址進行復用;
呼叫close之後,強制關閉,不經歷time_wait階段,再對位址進行復用。
還對監聽套接字設定了非阻塞方式,該函式實現具體如下:
int make_socket_non_blocking(int fd)
// 初始化請求資料結構
// 註冊新描述符
int tk_epoll_add(int epoll_fd, int fd, tk_http_request_t* request, int events)
前面我們提到,epoll_event中有乙個變數是聯合體,epoll_data_t,中經常使用裡面的fd,用來指向事件的檔案描述符,這還不夠用,當et觸發執行緒從socket中讀取資料之後,等待下一次資料到來之前需要將現在的資料存起來,記錄已經收到的長度這個時候有兩種做法:
使用map將fd作為key,通過每次索引找到fd對應的上下文結構體;
使用epoll_data_t裡的指標ptr,將詳細的fd資訊,上下文資訊儲存在乙個動態申請的結構體中,將結構體位置賦值給ptr就可以了,只需要維護好這個指標的生存期就行;(這是tkeed裡的方式,定義了乙個request結構體,為他分配了記憶體)。
epoll事件中的listen_fd時間的觸發方式有:有資料需要讀取和邊緣觸發。event結構體變數指向自定義結構體request。
TKeed原始碼分析之讀寫資料
socket通訊的讀寫 ssize t read int fd,void buf,size t count ssize t write int fd,const void buf,size t count tcp資料讀寫 include include ssize t recv int sockfd...
TKeed原始碼分析之監聽之後資料的接收與連線的關閉
遍歷events陣列,根據監聽種類及描述符型別分發操作 tk handle events epoll fd,listen fd,events,events num,conf.root,tp 分發處理函式 void tk handle events int epoll fd,int listen fd...
原始碼分析之LayoutInflater
簡介 inflate填充的過程 viewstub,merge,include的載入過程 layoutinflater系統服務的註冊過程 systemserviceregistry類有個靜態 塊,完成了常用服務的註冊,如下 static 註冊am registerservice context.act...