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-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( )
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( )
else :
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( )