<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                這里所說的錯誤有兩種: 1.http協議規定的錯誤,如404錯誤; 2.服務器運行過程中的錯誤,如write錯誤。 對于http協議規定的錯誤,這里的“錯誤”是針對客戶端的。lighttpd返回相應的錯誤提示文件之后,相當于順利的完成了一次請求,只是結果和客戶端想要的不一樣而已。 對于服務器運行中的錯誤,狀態機進入CON_STATE_ERROR狀態。常見的錯誤原因:客戶端提前斷開連接。比如你不停的刷新頁面,在你刷新的時候,前一次的連接沒有完成,但被瀏覽器強行斷開。對于服務器而言,刷新前后的兩個連接是不相干的,服務器在接收后一個連接的時候仍然會繼續處理前一次的連接。而前一次的連接已斷開,這就產生了連接錯誤。 進入CON_STATE_ERROR狀態后,如果前面的請求處理已經得到了結果。也就是http_status不為空。那么調用plugins_call_handle_request_done告訴插件請求處理結束: ~~~ /* even if the connection was drop we still have to write it to the access log */ if (con->http_status) { plugins_call_handle_request_done(srv, con); } ~~~ 如果使用了ssl,關閉ssl連接: ~~~ #ifdef USE_OPENSSL if (srv_sock->is_ssl) { /* 關閉ssl連接 */ } ERR_clear_error(); #endif ~~~ 接著: ~~~ switch(con->mode) { case DIRECT: #if 0 log_error_write(srv, __FILE__, __LINE__, "sd", "emergency exit: direct", con->fd); #endif break; default: switch(r = plugins_call_handle_connection_close(srv, con)) { case HANDLER_GO_ON: case HANDLER_FINISHED: break; default: log_error_write(srv, __FILE__, __LINE__, ""); break; } break; } connection_reset(srv, con); ~~~ 如果連接模式不是DIRECT,調用plugins_call_handle_connection_close告訴插件連接已經關閉。 如果設置了keep_alive,此時可能是服務器首先關閉連接的。調用shutdown關閉連接的讀和寫。如果關閉沒有出錯,狀態機進入CON_STATE_CLOSE狀態。如果沒有設置keep_alive或者shutdown調用失敗,那么直接關閉連接,結束狀態機的運行。 ~~~ /* close the connection */ if ((con->keep_alive == 1) && (0 == shutdown(con->fd, SHUT_WR))) { con->close_timeout_ts = srv->cur_ts; connection_set_state(srv, con, CON_STATE_CLOSE); if (srv->srvconf.log_state_handling) { log_error_write(srv, __FILE__, __LINE__, "sd", "shutdown for fd", con->fd); } } else { connection_close(srv, con); } con->keep_alive = 0; srv->con_closed++; ~~~ 注意到,這里服務器主動關閉連接的時候用的是shutdown而不是close: 1.close使用引用計數,在計數為0時才關閉套接字;shutdown不管引用計數,直接激發TCP的正常連接終止序列; 2.close終止讀和寫兩個方向的數據傳送;shutdown可以指定只關閉連接的讀,或只關閉連接的寫,或兩者均關閉。 以上lighttpd是關閉了連接的寫這一半,對于TCP套接字來說,這叫做半關閉:當前留在套接字發送緩沖區的數據仍然可以發送,但是進程不能再對其調用寫函數(由于讀端沒有關閉,所以服務器仍然可以讀數據),當數據發送完畢之后,TCP連接終止。 另外,注意一下:con->close_timeout_ts = srv->cur_ts;將close_timeout_ts的值設置為當前時間,在下面會用到。 在CON_STATE_CLOSE階段: ~~~ case CON_STATE_CLOSE: if (srv->srvconf.log_state_handling) { log_error_write(srv, __FILE__, __LINE__, "sds", "state for fd", con->fd, connection_get_state(con->state)); } if (con->keep_alive) { if (ioctl(con->fd, FIONREAD, &b)) { log_error_write(srv, __FILE__, __LINE__, "ss", "ioctl() failed", strerror(errno)); } if (b > 0) { char buf[1024]; log_error_write(srv, __FILE__, __LINE__, "sdd", "CLOSE-read()", con->fd, b); /* */ read(con->fd, buf, sizeof(buf)); } else { /* nothing to read */ con->close_timeout_ts = 0; } } else { con->close_timeout_ts = 0; } if (srv->cur_ts - con->close_timeout_ts > 1) { connection_close(srv, con); if (srv->srvconf.log_state_handling) { log_error_write(srv, __FILE__, __LINE__, "sd", "connection closed for fd", con->fd); } } break; ~~~ 如果緩沖區中還有數據,服務器會把數據讀出來(然后丟棄),以騰出內存空間。 如果沒有數據可讀,那么設置close_timeout_ts=0,關閉連接。 如果有數據可讀,讀取數據之后,連接依然處在CON_STATE_CLOSE狀態中(在出了CON_STATE_ERROR后,進入CON_STATE_CLOSE,這段時間cur_ts是沒有改變的。如果有數據可讀,此時const_time_ts是等于cur_ts的,因此連接并未被關閉),連接對應的fd被加入到fdevent系統中監聽讀事件。如果緩沖區中還有數據,那么在connection_handle_fdevent 函數中,也有上面這段代碼,再次運行之,直到數據讀完。隨著close_timeout_ts被設置為0,在下次joblist的調度中,狀態機將會關閉連接,清理所有資源。 至此,連接正式關閉。 關于狀態機的簡單解析就到此為止~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看