2013-02-06 143 views
0

我正在使用select()函數--I/O多路複用在python中構建Web服務器。我能夠連接到多個客戶端,在我的情況下是web瀏覽器(safari,chrome,firefox),並接受每個客戶端的HTTP 1.1 GET請求。一旦我收到請求,我將html頁面內容返回到顯示html頁面的瀏覽器。Python 2.7中的Web服務器:瀏覽器不顯示頁面

我得到的問題是當我嘗試保持連接打開一段時間。我意識到我無法在瀏覽器中顯示任何內容,除非我使用fd.close()關閉連接。

這裏是我用來接受和響應瀏覽器請求的功能。問題是我使用fd.sendall()後,我不想關閉連接,但頁面不會顯示,直到我做。請幫忙!任何幫助或建議表示讚賞..

def handleConnectedSocket(): 
    try: 
     recvIsComplete = False 
     rcvdStr = '' 

     line1 = "HTTP/1.1 200 OK\r\n" 
     line2 = "Server: Apache/1.3.12 (Unix)\r\n" 
     line3 = "Content-Type: text/html\r\n" # Alternately, "Content-Type: image/jpg\r\n" 
     line4 = "\r\n" 

     line1PageNotFound = "HTTP/1.1 404 Not Found\r\n" 
     ConnectionClose = "Connection: close\r\n" 

     while not recvIsComplete: 
      rcvdStr = fd.recv(1024) 

      if rcvdStr!= "" : 

# look for the string that contains the html page 
       recvIsComplete = True 
       RequestedFile = "" 
       start = rcvdStr.find('/') + 1 
       end = rcvdStr.find(' ', start) 
       RequestedFile = rcvdStr[start:end] #requested page in the form of xyz.html 

       try: 
        FiletoRead = file(RequestedFile , 'r') 
       except: 
        FiletoRead = file('PageNotFound.html' , 'r') 
        response = FiletoRead.read() 
        request_dict[fd].append(line1PageNotFound + line2 + ConnectionClose + line4) 
        fd.sendall(line1PageNotFound + line2 + line3 + ConnectionClose + line4 + response) 
#     fd.close() <--- DONT WANT TO USE THIS 
       else:  
        response = FiletoRead.read() 
        request_dict[fd].append(line1 + line2 + line3 + ConnectionClose + line4 + response) 
        fd.sendall(line1 + line2 + line3 + line4 + response) 
#     fd.close() <--- DONT WANT TO USE THIS 
      else: 
       recvIsComplete = True 
#Remove messages from dictionary 
       del request_dict[fd]  
       fd.close() 

客戶端(瀏覽器)的請求是HTTP 1.1的形式,如下所示:

GET /Test.html HTTP/1.1 
Host: 127.0.0.1:22222 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
+0

你壓痕有點混了(看看你的',而不是recvIsComplete'部分) - 也'file' (推薦使用「open」),所以我不認爲你需要一個'python-3.x'標籤,所以我已經刪除它了。 –

+0

我添加了python 3.x,因爲我認爲這個問題不僅僅是python 2.7相關。我正在尋找建議和任何建議,我如何解決這個問題。即使是一個python 3.x人也可以提出解決方案。 – CarbonD1225

+0

Okies-然後沒有特定的版本標籤;) –

回答

1

Connection: close指示瀏覽器,你會告訴它,當你」重新通過關閉連接發送數據。既然你不想這樣做,你可能會想爲Connection使用不同的值,如Keep-Alive。但是,如果您使用該功能,那麼您還需要發送Content-Length或執行其他操作,以便瀏覽器知道您何時完成數據發送。

即使您沒有使用Keep-AliveContent-Length也是一件好事,因爲它允許瀏覽器瞭解當前下載頁面的進度。如果你有一個很大的文件你發送,並不發送Content-Length,瀏覽器不能,例如,顯示進度條。 Content-Length啓用。

那麼你如何發送一個Content-Length頭?計算您要發送的數據的字節數。把它變成一個字符串並將其用作值。就這麼簡單。例如:

# Assuming data is a byte string. 
# (If you're dealing with a Unicode string, encode it first.) 
content_length_header = "Content-Length: {0}\r\n".format(len(data)) 

下面是一些代碼的工作對我來說:

#!/usr/bin/env python3 
import time 
import socket 

data = b'''\ 
HTTP/1.1 200 OK\r\n\ 
Connection: keep-alive\r\n\ 
Content-Type: text/html\r\n\ 
Content-Length: 6\r\n\ 
\r\n\ 
Hello!\ 
''' 


def main(server_address=('0.0.0.0', 8000)): 
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) 
    server.bind(server_address) 
    server.listen(5) 
    while True: 
     try: 
      client, client_address = server.accept() 
      handle_request(client, client_address) 
     except KeyboardInterrupt: 
      break 


def handle_request(client, address): 
    with client: 
     client.sendall(data) 
     time.sleep(5) # Keep the socket open for a bit longer. 
     client.shutdown(socket.SHUT_RDWR) 


if __name__ == '__main__': 
    main() 
+0

嗯。我可以嘗試使用Connection:Keep-live。你能給我一個關於如何使用內容長度的例子嗎?以及如何計算價值? – CarbonD1225

+1

您需要了解一些HTTP,特別是[如何確定或聲明消息長度](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4) –

+0

謝謝@icktoofay。但它似乎還沒有顯示任何東西。我發送以下內容作爲響應: 'HTTP/1.1 200 OK \ r \ n服務器:Apache/1.3.12(Unix)\ r \ n內容長度:207 \ r \ n連接:保持活動\ r \ n \ r \ n ....'以及HTML正文。有什麼建議麼? – CarbonD1225

相關問題