python socket处理keepalive请求

Posted

技术标签:

【中文标题】python socket处理keepalive请求【英文标题】:python socket handle keepalive request 【发布时间】:2016-01-21 04:46:41 【问题描述】:

我正在使用 python 编写一个简单的 Web 服务器,并向它发送请求。我使用 libevent 作为我的 http 客户端。但是每次我发送 keep-alive 请求时,http 连接都会在成功回调之前关闭回调。我认为这可能是保活问题。这是我的python(服务器)代码:

import socket

HOST, PORT = '', 8999

listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
listen_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60)
listen_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 4)
listen_socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 15)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
print 'Serving HTTP on port %s ...' % PORT
while True:
    client_connection, client_address = listen_socket.accept()
    request = client_connection.recv(1024)
    print request

    http_response = """\
    HTTP/1.1 200 OK

    Hello, World!
    """

    client_connection.sendall(http_response)
    client_connection.close()

【问题讨论】:

【参考方案1】:

但是每次我发送一个keep-alive请求时,...

我认为您混淆了应用层 HTTP keep-alive 和传输层 TCP keep-alive。

客户端使用 HTTP keep-alive 向服务器建议底层 TCP 连接应保持打开状态,以便客户端的进一步请求。但是服务器可能会拒绝,并且您的服务器在处理客户端请求后会显式关闭连接,即完成发送响应。除此之外,服务器发送响应的方式使得 HTTP 无法保持活动状态,因为响应的长度是未知的,因此仅在底层 TCP 连接结束时结束。要解决此问题,您需要指定 Content-length 或使用分块传输编码。

TCP 保持连接用于检测连接中断,即一侧崩溃、路由器死机或类似情况。除了名称相似外,它与 HTTP keep-alive 完全无关。它是用 setsockopt 设置的,这就是你正在做的事情。但是在 TCP keep-alive 的情况下,没有可以显式发送的 keep-alive 请求。

【讨论】:

谢谢,我真的把 HTTP keep-alive 和 TCP keep-alive 搞混了。而我使用 BaseHTTPServer 解决了这个问题。但是我还是很好奇如何使用上面的代码来支持HTTP keep-alive。我尝试添加 Content-LengthConnection 标头,但它仍然不起作用。 @XiaoyingWang:我不知道你是怎么做到的(没有代码),所以我无能为力。我建议用代码提出一个新问题。

以上是关于python socket处理keepalive请求的主要内容,如果未能解决你的问题,请参考以下文章

socket keepalive理解

当所有连接断开时,启用 KeepAlive 的 C# Socket 不会发送

TCP心跳 | TCP keepAlive(转)

HTTP keepalive详解

TCP socket如何判断连接断开

压测过程中的KeepAlive