繁体   English   中英

我正在使用 python 套接字来构建 HTTPServer,但我的 css 响应保持挂起

[英]I am using python socket to build HTTPServer, but my css response keep pending

我正在制作一个 httpServer。 当客户端输入localhost:8888/good.html时,会被路由到对应的页面。

我感到困惑的是,我的 css 响应( res_for_style )一直处于等待状态。 请让我知道我哪里错了。

服务器.py

import socket
import json
import sys
import threading

pars = ('127.0.0.1', 8888)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(pars)
s.listen(5)

res_for_good = '''HTTP/1.1 200 OK
Content-Type: text/html

<head>
<link rel="stylesheet" href="./style.css" type="text/css">
</head>
<html>
<body>good HaHa</body>
</html>
'''

res_for_style='''HTTP/1.1 200 OK
Content-Type: text/css

body{
    color: red;
}
'''

def serveClient(clientsocket, address):
    while True:
        data = clientsocket.recv(1024)
        data_utf8=data.decode('utf-8').split('\r\n')

        if '/good.html' in data_utf8[0]:
            clientsocket.sendall(res_for_good.encode())
        
        if '/style.css' in data_utf8[0]:
            print("transfer css")
            res="Content-Type: text/css\n\n"+css_file.read()
            clientsocket.sendall(res_for_style.encode())

        if data == b'':
            clientsocket.close()
            break

while True:
    (clientsocket, address) = s.accept()
    threading.Thread(target = serveClient, args = (clientsocket, address)).start()

正如您已经注意到的, clientsocket.close()将解决您的问题。

其背后的原因如下:

HTTP 使用 TCP 连接,它表示消息的恒定 stream。 HTTP 协议定义了消息的结构。 这种结构需要达成一致; 否则,就不可能进行有益的交流。

消息本身分为两部分,标题和正文。 虽然正文携带有效负载(HTML、CSS 或其他任何内容),但标头包含有关以下有效负载的必要元数据。 header 的一个示例是您已经使用的Content-Type: text/css

要知道接收到的正文是否已完全传输,接收方有两个选择: 检查接收到的正文的长度是否与预期正文的长度匹配,如Content-Length header 所定义。 如果缺少Content-Length header,则知道传输是否完成的唯一方法是检查发送方是否关闭了连接。 如果这两种情况都没有发生,则客户端假定服务器将发送更多信息并继续等待。

这就是关闭套接字可以解决您的问题的原因。

注意:HTTP 比我刚才描述的行为要复杂得多。 例如,有分块响应,其工作方式与描述的不同。 更不用说keep-alive 有关更多参考资料,请参阅此问题阅读文档

我觉得搭建一个简单的HTTP服务器是一次很棒的学习体验。 但我建议您使用框架,如 Flask 或 Django,如果您打算在生产中使用它。

我发现我可以通过在每个 while 循环中添加clientsocket.close()来解决它,但我仍然不知道为什么。

def serveClient(clientsocket, address):
    while True:
        data = clientsocket.recv(1024)
        data_utf8=data.decode('utf-8').split('\r\n')

        if '/good.html' in data_utf8[0]:
            clientsocket.sendall(res_for_good.encode())
        
        if '/style.css' in data_utf8[0]:
            print("transfer css")
            res="Content-Type: text/css\n\n"+css_file.read()
            clientsocket.sendall(res_for_style.encode())

        clientsocket.close() #I find that I can solve it by adding this line         

        if data == b'':
            clientsocket.close()
            break

暂无
暂无

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

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