我正在使用 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
) 一直处于待处理状态。请让我知道哪里错了。
Server.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()
我发现我可以通过在每个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
正如您已经注意到的,clientsocket.close()
将解决您的问题。
原因如下:
HTTP 使用 TCP 连接,它代表一个恒定的消息流。
HTTP 协议定义消息的结构。这种结构需要商定;否则,将无法进行有益的沟通。
消息本身分为两部分,Headers 和 body。
虽然 body 携带有效负载(HTML、CSS 或其他任何内容),但 header 包含有关以下有效负载的必要元数据。 header 的一个示例是您已经使用的 Content-Type: text/css
。
要知道接收到的body是否已经完全传输,接收方有两种选择:
检查接收到的 body 的长度是否与 body 预期的 body 的长度匹配,如 Content-Length
header 所定义。如果 Content-Length
header 丢失,则知道传输是否完成的唯一方法是检查发送方是否已关闭连接。
如果这两种情况都没有发生,则客户端认为服务器会发送更多信息并继续等待。
这就是为什么关闭套接字可以解决您的问题。
注意:
HTTP 比我刚才描述的行为要复杂得多。
例如,有分块响应,其工作方式与描述的不同。更不用说keep-alive
了。
有关更多参考,请参阅 this question or read the documentation。
我认为构建一个简单的 HTTP 服务器是一次很棒的学习经历。
但是如果你打算在生产中使用它,我建议你使用一个框架,比如 Flask 或 Django。
我正在制作一个httpServer。当客户端输入localhost:8888/good.html
时,他将被路由到相应的页面。
让我感到困惑的是,我的 css 响应 (res_for_style
) 一直处于待处理状态。请让我知道哪里错了。
Server.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()
我发现我可以通过在每个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
正如您已经注意到的,clientsocket.close()
将解决您的问题。
原因如下:
HTTP 使用 TCP 连接,它代表一个恒定的消息流。 HTTP 协议定义消息的结构。这种结构需要商定;否则,将无法进行有益的沟通。
消息本身分为两部分,Headers 和 body。
虽然 body 携带有效负载(HTML、CSS 或其他任何内容),但 header 包含有关以下有效负载的必要元数据。 header 的一个示例是您已经使用的 Content-Type: text/css
。
要知道接收到的body是否已经完全传输,接收方有两种选择:
检查接收到的 body 的长度是否与 body 预期的 body 的长度匹配,如 Content-Length
header 所定义。如果 Content-Length
header 丢失,则知道传输是否完成的唯一方法是检查发送方是否已关闭连接。
如果这两种情况都没有发生,则客户端认为服务器会发送更多信息并继续等待。
这就是为什么关闭套接字可以解决您的问题。
注意:
HTTP 比我刚才描述的行为要复杂得多。
例如,有分块响应,其工作方式与描述的不同。更不用说keep-alive
了。
有关更多参考,请参阅 this question or read the documentation。
我认为构建一个简单的 HTTP 服务器是一次很棒的学习经历。 但是如果你打算在生产中使用它,我建议你使用一个框架,比如 Flask 或 Django。