import socket
import os
import re
import time
from multiprocessing import Process
class CHttpServer(object):
"""Httpserver服务端类"""
def __init__(self):
self.m_serverSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.m_serverSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.m_buf_size = 8 * 1024 * 1024
def start(self):
self.m_serverSocket.listen(128)
while(True):
m_clientSocket,m_clientAddr = self.m_serverSocket.accept()
m_clientSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
print("创建的socket是", end="")
print(m_clientSocket)
print('[%s,%s]用户连接上了服务器' % m_clientAddr)
handle_client_process = Process(target = self.handle_client,args=(m_clientSocket,))
handle_client_process.start()
m_clientSocket.close()
#数据处理进程
def handle_client(self,clientSocket):
'''
处理客户请求操作
'''
#获取客户请求数据
print("进程:", end="")
print(os.getpid())
request_data = clientSocket.recv(2048)
print('接收到的数据:%s' % request_data)
request_lines=request_data.splitlines()
bytes_start = ""
bytes_end = ""
req_method = str(request_lines[0], encoding="utf8").split("/")[0].strip()
print(req_method)
print(req_method)
req_data_byte_status = False
if req_method == "GET":
for line in request_lines:
print(str(line))
if "Range" in str(line, encoding="utf8") or "range" in str(line, encoding="utf8") :
bytes_start, bytes_end = self.parse_range(str(line, encoding="utf8"))
req_data_byte_status = True
file_size = os.path.getsize("test.mp4")
if req_data_byte_status:
if bytes_end == "" and bytes_start == "0" : # 说明全部读取
response_start_line = "HTTP/1.1 206 Partial Content\r\n"
response_headers = "Server: My server\r\n"
response_headers = response_headers + "Accept-Ranges: bytes\r\n"
# response_headers = response_headers + "Content-Length: {}\r\n".format(str(file_size))
response_headers = response_headers + "Content-Length: {}\r\n".format(str(file_size))
response_headers = response_headers + "Content-Range: bytes 0-{}/{}\r\n".format(str(file_size-1), file_size)
response_headers = response_headers + "Content-Type: video/mp4\r\n"
response = response_start_line + response_headers + "\r\n"
clientSocket.send(bytes(response, "utf8")) # 到底是不是这种模式
videofile = open("test.mp4", "rb")
while True:
video_bytes = videofile.read(self.m_buf_size)
if not video_bytes: #文件读取完毕
break
print("socket status :", end="")
print(clientSocket)
try:
clientSocket.send(video_bytes)
except Exception as e:
print(e)
break
videofile.close()
clientSocket.close() # 这里如果不 close, 这个子进程结束运行后
else:
bytes_start = int(bytes_start)
if bytes_start >= file_size:
response_body = "<html><head><title>416 Requested Range Not Satisfiable</title></head><body><center><h1>416 Requested Range Not Satisfiable</h1></center><hr><center>nginx/1.18.0</center></body></html>"
response_start_line = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n"
response_headers = "Server: My server\r\n"
response_headers = response_headers + "Accept-Ranges: bytes\r\n"
response_headers = response_headers + "Content-Length: {}\r\n".format(len(response_body))
response_headers = response_headers + "Content-Type: text/html\r\n"
response_headers = response_headers + "Content-Range: bytes */{}\r\n".format(str(file_size))
response = response_start_line + response_headers + "\r\n"
response = response + response_body
clientSocket.send(bytes(response, "utf8"))
clientSocket.close()
else:
if bytes_end != "" :
bytes_end = int(bytes_end)
else:
bytes_end = file_size - 1
need_get_size = bytes_end - bytes_start + 1
total_get_size = 0
response_start_line = "HTTP/1.1 206 Partial Content\r\n"
response_headers = "Server: My server\r\n"
response_headers = response_headers + "Accept-Ranges: bytes\r\n"
response_headers = response_headers + "Content-Length: {}\r\n".format(
str(bytes_end - bytes_start + 1))
response_headers = response_headers + "Content-Type: video/mp4\r\n"
response_headers = response_headers + "Content-Range: bytes {}-{}/{}\r\n".format(str(bytes_start), str(bytes_end), file_size)
response = response_start_line + response_headers + "\r\n"
print(response)
clientSocket.send(bytes(response, "utf8"))
videofile = open("test.mp4", "rb")
videofile.seek(bytes_start, 0)
while True:
if self.m_buf_size < need_get_size:
video_bytes = videofile.read(self.m_buf_size)
if not video_bytes: # 说明文件读取完毕
break
print("-"*25)
print(need_get_size)
try:
clientSocket.send(video_bytes)
except Exception as e:
print(e)
break
need_get_size = need_get_size - len(video_bytes)
else:
video_bytes = videofile.read(need_get_size)
if not video_bytes: # 说明文件读取完毕
break
try:
clientSocket.send(video_bytes)
except Exception as e:
print(e)
break
break
videofile.close()
clientSocket.close() # 这里如果不 close, 这个子进程结束运行后, socket会不会自己close掉
else:
# response_start_line = "HTTP/1.1 206 Partial Content\r\n" QT 播放器 在这里会失败
response_start_line = "HTTP/1.1 200 ok\r\n"
response_headers = "Server: My server\r\n"
response_headers = response_headers + "Accept-Ranges: bytes\r\n"
response_headers = response_headers + "Content-Length: {}\r\n".format(str(file_size))
response_headers = response_headers + "Content-Range: bytes 0-{}/{}\r\n".format(str(file_size - 1),
file_size)
response_headers = response_headers + "Content-Type: video/mp4\r\n"
response = response_start_line + response_headers + "\r\n"
clientSocket.send(bytes(response, "utf8")) # 到底是不是这种模式
print(response)
videofile = open("test.mp4", "rb")
while True:
video_bytes = videofile.read(self.m_buf_size)
if not video_bytes: # 文件读取完毕
break
print("socket status :", end="")
print(clientSocket)
try:
clientSocket.send(video_bytes)
except Exception as e:
print(e)
break
videofile.close()
clientSocket.close()
def parse_range(self, part_header):
'''
解析出请求中的 range start end
:return: start end
'''
print(part_header)
temp = part_header.split(":")
temp = temp[1].split("=")
temp = temp[1].split("-")
start = temp[0]
end = ""
if len(temp) == 2:
end = temp[1]
return start, end
def get_file_info(self, url):
pass
#绑定端口
def bind(self,port):
self.m_serverSocket.bind(('',port))
def parseline(self,strcon):
"""解析字符串"""
pass
def main():
http_server = CHttpServer()
http_server.bind(8000)
http_server.start()
if __name__ == "__main__":
main()
# http://127.0.0.1:8000
12-25