我正在使用 python 套接字撰寫一個持久的 http 服務器。我認為style.css檔案應該通過相同的埠號傳輸,但似乎我沒有得到結果。資料包 48 和 49 顯示與資料包 37 相比,style.css 是通過不同的埠傳輸的。
我認為 res_for_good 的標題可能有問題。
import socket
from datetime import datetime
import threading
res_for_good = '''HTTP/1.1 200 OK\r
Date: Sun, 18 Oct 2012 10:36:20 GMT\r
Accept-Ranges: bytes\r
Content-Type: text/html; charset=iso-8859-1\r
Connection: keep-alive\r
Keep-Alive: timeout=3 max=5\r
Content-Length: 112\r
\r
<head>
<link rel="stylesheet" href="./style.css" type="text/css">
</head>
<html>
<body>good HaHa</body>
</html>
'''
res_for_notfound='''HTTP/1.1 404 Not Found\r
Date: Sun, 18 Oct 2012 10:36:20 GMT\r
Accept-Ranges: bytes\r
Content-Type: text/html; charset=iso-8859-1\r
Connection: keep-alive\r
Keep-Alive: timeout=3 max=5\r
Content-Length: 116\r
\r
<head>
<link rel="stylesheet" href="./style.css" type="text/css">
</head>
<html>
<body>404 Not Found</body>
</html>
'''
res_for_style='''HTTP/1.1 200 OK\r
Date: Sun, 18 Oct 2012 10:36:20 GMT\r
Accept-Ranges: bytes\r
Content-Type: text/css; charset=iso-8859-1\r
Keep-Alive: timeout=3 max=5\r
Connection: keep-alive\r
Content-Length: 46\r
\r
body{
color: red;
font-size: 100px;
}
'''
def serveClient(clientsocket, address):
start = datetime.now()
objcount=0
# we need a loop to continuously receive messages from the client
while True:
objcount =1
# then receive at most 1024 bytes message and store these bytes in a variable named 'data'
# you can set the buffer size to any value you like
data = clientsocket.recv(1024)
data_utf8=data.decode('utf-8').split('\r\n')
#data_json = json.loads(data_utf8)
print(address)
print(data)
# if the received data is not empty, then we send something back by using send() function
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()
res=res_for_style
clientsocket.sendall(res_for_style.encode())
if '/redirect.html' in data_utf8[0]:
clientsocket.sendall(res_for_redirect.encode())
elif data:
clientsocket.sendall(res_for_notfound.encode())
if data == b'':
objcount-=1
print("object count: " str(objcount))
now = datetime.now()
# we need some condition to terminate the socket
# lets see if the client sends some termination message to the server
# if so, then the server close the socket
if objcount == max_rec_Object or (now-start).total_seconds()>waiting_time:
print(start)
print(now)
print('close socket')
clientsocket.close()
break
while True:
# accept a new client and get it's informati
# print(socket.gethostbyaddr(s.getpeername))
(clientsocket, address) = s.accept()
# create a new thread to serve this new client
# after the thread is created, it will start to execute 'target' function with arguments 'args'
threading.Thread(target = serveClient, args = (clientsocket, address)).start()

uj5u.com熱心網友回復:
我認為 style.css 檔案應該通過相同的埠號傳輸
首先,HTTP/1.1 中沒有這樣的要求。然后,您的代碼中存在錯誤。
首先是錯誤:從資料包捕獲中可以看出,您的服務器/good.html使用 3 個 HTTP 回應回應單個請求:一個是預期的 200,另外兩個是意外的 404。第一個錯誤的 404 是由于以下代碼:
if '/good.html' in data_utf8[0]:
clientsocket.sendall(res_for_good.encode())
...
if '/redirect.html' in data_utf8[0]:
clientsocket.sendall(res_for_redirect.encode())
elif data:
clientsocket.sendall(res_for_notfound.encode())
由于它在處理后不會停止,/good.html因此最終會出現在最后顯示的行中并發送 res_for_notfound.
第二個錯誤 404 是由于以下代碼:
while True: ... data = clientsocket.recv(1024) ... elif 資料:clientsocket.sendall(res_for_notfound.encode())
這里盲目假設請求不會超過 1024 并且它將在單個recv. 這兩個假設都是錯誤的。從抓包可以看出,請求實際上是1098位元組(看ACK=1099)。即使它小于 1024,也不能保證它會在單個 內被讀取recv,這不是 TCP 的作業方式。
由于兩個無關的 404 回應,客戶端正確地假定服務器無法發送正確的回應,因此關閉連接以恢復正常狀態。
也就是說,即使有正確的回應,也不能保證第二個請求通過相同的 TCP 連接進入。顯式或隱式宣布支持 HTTP 保持活動只是意味著客戶端和服務器支持對另一個 HTTP 請求重用 TCP 連接。這并不意味著一個特定的現有的TCP連接必須用于下一個請求,也沒有任何現有的TCP連接,必須不惜一切,而不是創建一個新的使用。
從抓包中可以看出,瀏覽器最初打開了兩個到服務器的TCP連接。這并不少見,因為通常一個站點包含許多應盡快檢索的資源。只有 HTTP/1.1 只能通過單個 TCP 連接順序而不是并行地檢索資源。因此,準備另一個備用 TCP 連接是個好主意。然后在您的情況下將另一個現有的連接用于新資源。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/377923.html
標籤:Python html 插座 协议 python-sockets
上一篇:客戶端斷開連接中的段錯誤
