代码之家  ›  专栏  ›  技术社区  ›  Filipe

通过http python发送图像

  •  3
  • Filipe  · 技术社区  · 6 年前

    我需要在不使用http库的情况下构建http服务器。

    我已经运行了服务器并加载了一个html页面,但我的 <img src="..."/> 标签未加载,我收到了呼叫,但无法在页面中预设png/JPEG。

    httpServer。py公司

    # Define socket host and port
    SERVER_HOST = '0.0.0.0'
    SERVER_PORT = 8000
    
    # Create socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind((SERVER_HOST, SERVER_PORT))
    server_socket.listen(1)
    print('Listening on port %s ...' % SERVER_PORT)
    
    while True:
        # Wait for client connections
        client_connection, client_address = server_socket.accept()
    
        # Handle client request
        request = client_connection.recv(1024).decode()
        content = handle_request(request)
    
        # Send HTTP response
        if content:
            response = 'HTTP/1.1 200 OK\n\n'
            response += content
        else:
            response = 'HTTP/1.1 404 NOT FOUND\n\nFile Not Found'
    
        client_connection.sendall(response.encode())
        client_connection.close()
    
    # Close socket
    server_socket.close()
    

    处理调用的函数

     def handle_request(request):
        http = HttpHandler.HTTPHandler
    
        # Parse headers
        print(request)
        headers = request.split('\n')
        get_content = headers[0].split()
    
        accept = headers[6].split()
        type_content = accept[1].split('/')
    
        try:
            # Filename
            filename = get_content[1]
    
            if get_content[0] == "GET":
                content = http.get(None, get_content[1], type_content[0])
    
    
            return content
        except FileNotFoundError:
            return None
    

    类来处理http谓词

    class HTTPHandler:
    
        def get(self, args, type):
            if args == '/':
                args = '/index.html'
                fin = open('htdocs' + args)
            if type != "image":
                fin = open('htdocs/' + args)
    
            if type == "image":
                fin = open('htdocs/' + args, 'rb')
    
            # Read file contents
            content = fin.read()
            fin.close()
            return content
    

    要知道,我正在尝试制作一个HTTP 1.1,如果您看到任何不正常的情况,可以提前说声谢谢。

    2 回复  |  直到 5 年前
        1
  •  3
  •   Community CDub    3 年前

    我不知道你从哪里学到了HTTP的工作原理,但我很确定你没有学习 the actual standard 在实现协议时应该执行的操作。有关实施的一些注意事项:

    • 线端应为 \r\n \n 。这对于作为客户端请求的服务器响应都是正确的。
    • 您假设客户机请求的大小永远不会超过1024字节,并且可以在一个小时内读取 recv 。但是,请求可以具有任意长度,并且不能保证您在一个 recv公司 (TCP是一种流协议,而不是消息协议)。
    • 虽然只需在主体之后关闭TCP连接就可以了,但最好将主体的长度包含在 Content-length 标头或使用分块传输编码。
    • 应使用 Content-Type 标题,即。 Content-type: text/html 对于HTML和 Content-type: image/jpeg 对于JPEG图像。如果没有此浏览器,可能会正确或错误地猜测类型,或者根据上下文也可能坚持使用正确的内容类型标题。

    除此之外,如果您调试这些问题,那么找出客户端和服务器之间实际交换的内容会很有帮助。可能是您自己检查了这个问题,但您没有在问题中包含此类信息。您唯一的错误描述是 “…我收到了呼叫,但无法在页面中预设png/JPEG” 然后是代码转储。

        2
  •  1
  •   Filipe    6 年前

    httpServer。py公司

    结果是:

    while True:
    # Wait for client connections
    client_connection, client_address = server_socket.accept()
    
    # Handle client request
    request = client_connection.recv(10240).decode()
    content = handle_request(request)
    
    # Send HTTP response
    if content:
        if str(content).find("html") > 0:
            client_connection.send('HTTP/1.1 200 OK\n\n'.encode())
            client_connection.send(content.encode())
        else:
            client_connection.send('HTTP/1.1 200 OK\r\n'.encode())
            client_connection.send("Content-Type: image/jpeg\r\n".encode())
            client_connection.send("Accept-Ranges: bytes\r\n\r\n".encode())
            client_connection.send(content)
    else:
        response = 'HTTP/1.1 404 NOT FOUND\r\nFile Not Found'
    
    client_connection.close()
    

    Get方法如下:

    class HTTPHandler:
    
    def get(self, args, type):
        if args == '/':
            args = '/index.html'
            fin = open('htdocs' + args)
        if type != "image":
            fin = open('htdocs/' + args)
    
        if type.find("html") == -1:
            image_data = open('htdocs/' + args, 'rb')
            bytes = image_data.read()
    
            # Content-Type: image/jpeg, image/png \n\n
            content = bytes
            fin.close()
            return content
    
        # Read file contents
        content = fin.read()
        fin.close()
        return content