Lighttpd 處理兩類錯誤:HTTP 協議規定錯誤(如 404)與服務器運行時錯誤(如 write 失敗)。前者返回錯誤提示頁面,對狀態機屬正常完成請求;後者直接進入 CON_STATE_ERROR 狀態,多由客戶端提前斷開連接導致(如瘋狂刷新頁面)。
http_status 非空),呼叫 plugins_call_handle_request_done 通知插件請求處理結束。DIRECT,呼叫 plugins_call_handle_connection_close 通知插件連接關閉。keep_alive:直接關閉連接、清理資源,狀態機結束。keep_alive:呼叫 shutdown 關閉讀寫,無錯誤則進入 CON_STATE_CLOSE,記錄 close_timeout_ts = cur_ts。此狀態下,若緩衝區有未讀數據則讀取並丟棄;無數據則設 close_timeout_ts = 0。隨後執行:
if (srv->cur_ts - con->close_timeout_ts > 1) {
connection_close(srv, con); // 最終清理:close、歸還連接池等
// 記錄日志...
}
close:減少引用計數,歸零時釋放資源。shutdown:針對 socket,可單向關閉(讀或寫);共享連接時,一進程呼叫即影響所有進程;shutdown 後仍可讀取緩衝區殘留數據,但需最終呼叫 close 釋放資源。TCP 協議下主動關閉方進入 TIME_WAIT(預設 4 分鐘),高併發下會耗盡端口與記憶體。雖不可避免,但可透過 shutdown 後讀取殘留數據釋放緩衝區記憶體來緩解。
if (ioctl(con->fd, FIONREAD, &b)) { /* 錯誤處理 */ }
if (b > 0) {
char buf[1024];
read(con->fd, buf, sizeof(buf)); // 讀取並丟棄
} else {
con->close_timeout_ts = 0; // 觸發下次 joblist 循環關閉連接
}
若有數據,持續在 connection_handle_fdevent 中重複讀取直到排空;隨 close_timeout_ts 歸零,下次調度將徹底關閉連接、清理所有資源。
至此連接正式關閉。具體效果取決於系統內核對緩衝區的處理,歡迎內行指教。