2013-02-06 98 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

相关问题