如何防止由于服务器关闭套接字而导致curl中的“连接被对等重置”

问题描述 投票:0回答:2

我制作了一个基本的http服务器(我正在开发自己的服务器,因为我想在稍后阶段进行低级http分析和操作):

import socket
import threading
import queue
import time

class SocketServer:
    """
        Basic Socket Server in python
    """

    def __init__(self,host,port,max_theads):
        self.host = host
        self.port = port
        self.server_socket = self.__initSocket()
        self.max_theands = max_theads
        self.request_queue = queue.Queue()        

    def __initSocket(self):
        return socket.socket(socket.AF_INET, socket.SOCK_STREAM)


    def __accept(self):
        self.server_socket.listen(5)
        while True:
            client_socket, client_address = self.server_socket.accept()    
            self.request_queue.put((client_socket, client_address))


    def __handle(self):
        while True:
            # Dequeue a request and process it
            client_socket, address = self.request_queue.get()    

            # Read HTTP Request
            # Log Http Request
            # Manipulate Http Request
            # Forward or respond

            client_socket.sendall(b"""HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<html><body>Hello World</body></html>\r\n""");
;
            time.sleep(1)
            client_socket.close()
            self.request_queue.task_done()


    def __initThreads(self):
        for _ in range(self.max_theands):
            threading.Thread(target=self.__handle, daemon=True).start()


    def start(self):
        self.server_socket.bind((self.host, self.port))
        self.__initThreads()
        self.__accept()

我将其启动到一个单独的进程中:

#!/usr/bin/env python3

"""
1. Read settings
2. Bootstrap Manupilator
3. Bootstrap Control Panel

"""
import multiprocessing
from manipulator.http_socket_server import SocketServer

if __name__ == "__main__":

    # @todo read settings file
    host = "0.0.0.0"
    port = 80
    max_threads = 5

    server = SocketServer(host, port, max_threads)
    server_process = multiprocessing.Process(target=server.start)
    server_process.start()

    # Add other main application code here if needed

    server_process.join()

但是curl收到:

curl 10.0.0.2
<html><body>Hello World</body></html>
curl: (56) Recv failure: Connection reset by peer

尽管

__handle
有延迟:

            time.sleep(1)

如何优雅地关闭套接字?

python python-3.x sockets curl
2个回答
0
投票

一个修复方法是发送内容长度标头:

content = '''<html><body>Hello World</body></html>\r\n'''.encode()
headers = f'''HTTP/1.1 200 OK\r\nContent-Length: {len(content)}\r\nContent-Type: text/html\r\n\r\n'''.encode()
client_socket.sendall(headers + content)

-1
投票

为了解决此问题,您需要先通知客户端 socker 正在关闭:

  client_socket.shutdown(socket.SHUT_RDWR)

这将为套接字关闭创建握手,如下所述:https://www.geeksforgeeks.org/tcp-connection-termination/

curl显示错误的原因:

curl: (56) Recv failure: Connection reset by peer

是因为

client_socket.close()
在没有先发送必要的握手的情况下终止了连接。

© www.soinside.com 2019 - 2024. All rights reserved.