Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7中的Web服务器:浏览器不显示页面_Python_Python 2.7_Network Programming - Fatal编程技术网

Python 2.7中的Web服务器:浏览器不显示页面

Python 2.7中的Web服务器:浏览器不显示页面,python,python-2.7,network-programming,Python,Python 2.7,Network Programming,我正在用python使用select()函数-I/O多路复用构建一个web服务器。我能够连接到多个客户端,在我的例子中,这些客户端是web浏览器(safari、chrome、firefox),并接受每个客户端的HTTP 1.1 GET请求。收到请求后,我将html页面内容返回到显示html页面的浏览器 我遇到的问题是,当我试图保持连接打开一段时间。我意识到,在使用fd.close()关闭连接之前,我无法在浏览器中显示任何内容 下面是我用来接受和响应浏览器请求的函数。问题是在我使用fd.senda

我正在用python使用select()函数-I/O多路复用构建一个web服务器。我能够连接到多个客户端,在我的例子中,这些客户端是web浏览器(safari、chrome、firefox),并接受每个客户端的HTTP 1.1 GET请求。收到请求后,我将html页面内容返回到显示html页面的浏览器

我遇到的问题是,当我试图保持连接打开一段时间。我意识到,在使用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()

Connection:close
向浏览器指示,当您通过关闭连接发送完数据后,您将告诉浏览器。因为您不想这样做,所以可能需要为
连接使用不同的值,如。但是,如果您使用该选项,那么您还需要发送
内容长度
或执行其他操作,以便浏览器知道您何时发送完数据

即使您没有使用
保持活动状态
内容长度
也可以发送,因为它可以让浏览器了解下载页面的当前进度。如果您正在发送一个大文件,但没有发送
内容长度
,那么浏览器就不能显示进度条<代码>内容长度
启用此功能

那么如何发送
内容长度
标题呢?计算要发送的数据字节数。将其转换为字符串并将其用作值。就这么简单。例如:

# 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()

您的缩进有点混乱(查看
而不是recvIsComplete
部分)-而且
文件
(建议改为
open
)已被弃用,因此我认为您不需要
python-3.x
标记,因此我删除了iti并添加了python 3.x,因为我认为这个问题不仅仅与python 2.7相关。我正在寻找关于如何解决这个问题的建议和任何建议。即使是Python3.x人员也可以建议一个解决方案。Okies-那么根本不需要特定于版本的标记;)更新:修复了缩进。有什么建议吗?这是一个学习练习吗?还是出于某种原因,你故意忽略了经过尝试和测试的框架(或者仅仅是Python自己的
SimpleHTTPServer
)?嗯,我可以尝试使用Connection:Keep live。你能给我一个关于如何使用内容长度的例子吗?那么如何计算这个值呢?您需要学习一些关于HTTP的知识,特别是感谢@icktoofay。但它似乎仍然没有显示任何东西。我将以下内容作为响应发送:
HTTP/1.1 200 OK\r\n服务器:Apache/1.3.12(Unix)\r\n内容长度:207\r\n连接:保持活动\r\n\r\n….
以及HTML正文。有什么建议吗?@user1319424:不幸的是,没有。我试着写了一个像这样的小服务器,并用Chrome、Firefox和Opera进行了尝试,并且在每一个服务器上都运行良好。我会把我的代码添加到我的答案中。嘿,终于成功了!我在做一些愚蠢的事情在别的地方。。。谢谢!我已将其标记为答案:)
#!/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()