2011-07-07 64 views
1

相應的初始化後,這裏是一個無限循環,以服務傳入的HTTPS請求,但每個請求只有一個連接(假設請求只需要一個讀):改變這一行是否實現持久保持連接?

while TRUE do 
    begin // wait for incoming TCP connection 
    if listen(listen_socket, 100) 0 then continue; // listen failed 
    client_len := SizeOf(sa_cli); 
    sock := accept(listen_socket, @sa_cli, @client_len); // create socket for connection 
    if sock = INVALID_SOCKET then continue; // accept failed 
    ssl := SSL_new(ctx); // TCP connection ready, create ssl structure 
    if assigned(ssl) then 
    begin 
    SSL_set_fd(ssl, sock); // assign socket to ssl structure 
    if SSL_accept(ssl) = 1 then // handshake worked 
     begin 
     bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); 
     if bytesin > 0 then 
     begin 
     buffer[bytesin] := #0; 
     // decide on response here... 
     response := 'HTTP/1.0 200 OK'#13#10 + etc; 
     SSL_write(ssl, pchar(response)^, length(response)); 
     end; // else read empty or failed 
     end; // else handshake failed 
    SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN or SSL_RECEIVED_SHUTDOWN); 
    CloseSocket(sock); 
    SSL_free(ssl); 
    end; // else ssl creation failed 
    end; // while 

正在改變

if ssl_accept(ssl) = 1 then 

while ssl_accept(ssl) = 1 do 

所有這一切都需要正確支持默認的HTTP 1.1保持活動(即,每個c的多個請求onnection)?

+0

假設整個請求將在一個讀呼叫滿足是導致失敗。 – EricLaw

+0

這樣做僅僅是爲了保持代碼簡潔並且不會分散問題。 –

回答

0

編號ssl_new()ssl_accept()每個連接只應調用一次。一旦連接和協商SSL會話,就不需要再次進行。 HTTP保持活動旨在避免每次請求都需要重新連接。您需要將呼叫循環至ssl_read()和SSL_write()。

此外,不要忘記檢查客戶端的HTTP版本。預計HTTP 1.1客戶端默認情況下會支持保活,而不必詢問它們。 HTTP 1.0和更早版本的客戶端必須明確包含'Connection:keep-alive'請求頭。無論哪種方式,服務器都需要發送一個'Connection:close'或者'Connection:keep-alive'響應頭來分別告知客戶端連接是關閉還是保持打開狀態。

基本上,你需要實現這種模型(僞代碼):

while True do 
begin 
    accept an incoming connection... 

    initialize SSL... 

    repeat 
    read a request... 
    if not Connected then Break; 

    KeepAlive := ((client is HTTP1.1+) and (request['Connection'] = '')) or (request['Connection'] = 'keep-alive'); 

    prepare reply... 
    response['Connection'] := iif(KeepAlive, 'keep-alive', 'close'); 

    send reply... 

    while KeepAlive and Connected; 

    cleanup SSL... 
    close socket... 
end; 
+0

這會產生更多的問題而不是答案,尤其是因爲你不清楚你在做什麼來確定「連接」。我將把這個問題重新發布爲一個更普遍的問題。另外請注意,服務器可以選擇返回「Connection:Close」並且不會打擾保持活動狀態。 –

+0

儘管請求可能會要求保持活動狀態,並且響應可能會使用該響應,但這並不意味着該連接實際上保證在下一個請求到達之前保持連接狀態。如果連接在請求之間閒置太久,或者客戶端本身可能決定在連接的末端執行該操作,則連接可能會通過防火牆/路由器來關閉連接。 OpenSSL會告訴你,當你嘗試讀取或寫入連接時,連接是否已經關閉。我相應地調整了我的僞代碼模型。 –

+0

因爲連接和請求沒有保證,所以我發佈了更通用的問題,問題6656090.我一直無法避免在阻塞套接字中卡住SSL_read ... –