首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Lighttpd 1.4.20 源碼分析:狀態機(四)錯誤處理與連接關閉機制

     編輯:關於.NET

Lighttpd 處理兩類錯誤:HTTP 協議規定錯誤(如 404)與服務器運行時錯誤(如 write 失敗)。前者返回錯誤提示頁面,對狀態機屬正常完成請求;後者直接進入 CON_STATE_ERROR 狀態,多由客戶端提前斷開連接導致(如瘋狂刷新頁面)。

CON_STATE_ERROR 處理流程

  1. 若前序處理已獲結果(http_status 非空),呼叫 plugins_call_handle_request_done 通知插件請求處理結束。
  2. 若使用 SSL,關閉 SSL 連接(代碼較長,多為錯誤處理)。
  3. 若連接模式非 DIRECT,呼叫 plugins_call_handle_connection_close 通知插件連接關閉。
  4. 未設 keep_alive:直接關閉連接、清理資源,狀態機結束。
  5. 已設 keep_alive:呼叫 shutdown 關閉讀寫,無錯誤則進入 CON_STATE_CLOSE,記錄 close_timeout_ts = cur_ts。

CON_STATE_CLOSE 狀態深度解析

此狀態下,若緩衝區有未讀數據則讀取並丟棄;無數據則設 close_timeout_ts = 0。隨後執行:

if (srv->cur_ts - con->close_timeout_ts > 1) {
    connection_close(srv, con); // 最終清理:close、歸還連接池等
    // 記錄日志...
}

shutdown 與 close 的關鍵差異

  • close:減少引用計數,歸零時釋放資源。
  • shutdown:針對 socket,可單向關閉(讀或寫);共享連接時,一進程呼叫即影響所有進程;shutdown 後仍可讀取緩衝區殘留數據,但需最終呼叫 close 釋放資源。

主動關閉連接的 TIME_WAIT 問題

TCP 協議下主動關閉方進入 TIME_WAIT(預設 4 分鐘),高併發下會耗盡端口與記憶體。雖不可避免,但可透過 shutdown 後讀取殘留數據釋放緩衝區記憶體來緩解。

CON_STATE_CLOSE 中的緩衝區排空邏輯

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 歸零,下次調度將徹底關閉連接、清理所有資源。

至此連接正式關閉。具體效果取決於系統內核對緩衝區的處理,歡迎內行指教。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved