简体   繁体   English

Python HTTP服务器在一段时间后给出错误

[英]Python HTTP server giving error some time after

I coded a Python HTTP server as below and I run the server from the directory which this python file exist. 我对Python HTTP服务器进行了如下编码,并从该python文件所在的目录运行该服务器。 I am typing "python myserver.py" in the cmd and server succesfully starts and reads the index.html in the directory but my problem is after some time my code gives the following error and closes the server 我在cmd中键入“ python myserver.py”,服务器成功启动并读取目录中的index.html,但是我的问题是一段时间后,我的代码给出以下错误并关闭了服务器

Traceback (most recent call last): File "myserver.py", line 20, in requesting_file = string_list[1] IndexError: list index out of range 追溯(最近一次呼叫最近):requesting_file = string_list [1]中的文件“ myserver.py”,第20行,IndexError:列表索引超出范围

How can I fix this problem ? 我该如何解决这个问题?

import socket

HOST,PORT = '127.0.0.1',8082

my_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
my_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
my_socket.bind((HOST,PORT))
my_socket.listen(1)

print('Serving on port ',PORT)

while True:
    connection,address = my_socket.accept()
    request = connection.recv(1024).decode('utf-8')
    string_list = request.split(' ')     # Split request from spaces

    print (request)

    method = string_list[0]
    requesting_file = string_list[1]

    print('Client request ',requesting_file)

    myfile = requesting_file.split('?')[0] # After the "?" symbol not relevent here
    myfile = myfile.lstrip('/')
    if(myfile == ''):
        myfile = 'index.html'    # Load index file as default

    try:
        file = open(myfile,'rb') # open file , r => read , b => byte format
        response = file.read()
        file.close()

        header = 'HTTP/1.1 200 OK\n'

        if(myfile.endswith(".jpg")):
            mimetype = 'image/jpg'
        elif(myfile.endswith(".css")):
            mimetype = 'text/css'
        else:
            mimetype = 'text/html'

        header += 'Content-Type: '+str(mimetype)+'\n\n'

    except Exception as e:
        header = 'HTTP/1.1 404 Not Found\n\n'
        response = '<html><body><center><h3>Error 404: File not found</h3><p>Python HTTP Server</p></center></body></html>'.encode('utf-8')

    final_response = header.encode('utf-8')
    final_response += response
    connection.send(final_response)
    connection.close()

socket.recv(n) is not guaranteed to read the entire n bytes of the message in one go and can return fewer bytes than requested in some circumstances. 不保证socket.recv(n)读取消息的整个n个字节,并且在某些情况下返回的字节数可能少于请求的字节数。

Regarding your code it's possible that only the method , or part thereof, is received without any space character being present in the received data. 关于您的代码,有可能仅接收到method或其一部分,而接收到的数据中没有任何空格字符。 In that case split() will return a list with one element, not two as you assume. 在这种情况下, split()将返回一个包含一个元素的列表,而不是您假设的两个元素。

The solution is to check that a full message has been received. 解决方案是检查是否已收到完整消息。 You could do that by looping until sufficient data has been received, eg you might ensure that some minimum number of bytes has been received by checking the length of data and looping until the minimum has been reached. 您可以通过循环直到收到足够的数据来做到这一点,例如,可以通过检查数据长度并循环直到达到最小值来确保已接收到一些最小字节数。

Alternatively you might continue reading until a new line or some other sentinel character is received. 或者,您可以继续阅读,直到收到新行或其他一些前哨字符。 It's probably worth capping the length of the incoming data to avoid your server being swamped by data from a rogue client. 最好限制传入数据的长度,以避免服务器被流氓客户端的数据淹没。

Finally, check whether split() returns the two values that you expect and handle accordingly if it does not. 最后,检查split()是否返回您期望的两个值,如果没有,则进行相应的处理。 Furthermore, be very careful about the file name; 此外,请注意文件名; what if it contains a relative path, eg ../../etc/passwd ? 如果它包含相对路径,例如../../etc/passwd怎么../../etc/passwd

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM