用python寫的簡單的http文件服務器demo

import socket
import os
import re
import time
from multiprocessing import Processclass 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 * 1024def 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 = Falseif 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 = Truefile_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: #文件讀取完畢breakprint("socket status :", end="")print(clientSocket)try:clientSocket.send(video_bytes)except Exception as e:print(e)breakvideofile.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_bodyclientSocket.send(bytes(response, "utf8"))clientSocket.close()else:if bytes_end != "" :bytes_end = int(bytes_end)else:bytes_end = file_size - 1need_get_size = bytes_end - bytes_start + 1total_get_size = 0response_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: # 說明文件讀取完畢breakprint("-"*25)print(need_get_size)try:clientSocket.send(video_bytes)except Exception as e:print(e)breakneed_get_size = need_get_size - len(video_bytes)else:video_bytes = videofile.read(need_get_size)if not video_bytes:  # 說明文件讀取完畢breaktry:clientSocket.send(video_bytes)except Exception as e:print(e)breakbreakvideofile.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:  # 文件讀取完畢breakprint("socket status :", end="")print(clientSocket)try:clientSocket.send(video_bytes)except Exception as e:print(e)breakvideofile.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, enddef get_file_info(self, url):pass#綁定端口def bind(self,port):self.m_serverSocket.bind(('',port))def parseline(self,strcon):"""解析字符串"""passdef main():http_server = CHttpServer()http_server.bind(8000)http_server.start()if __name__ == "__main__":main()# http://127.0.0.1:8000

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382411.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從《四驅兄弟》到“聯想中國”

《四驅兄弟》 小學的時候看過一個日本的動畫片叫四驅兄弟&#xff0c;里面就是一群小朋友代表國家各種比賽&#xff0c;其中讓我象比較深刻的是他把美國隊描述的非常邪惡&#xff0c;各種破壞別人的車子&#xff0c;通過卑鄙手段取得勝利。然后最后好像是正義戰勝邪惡的劇情還…

Mac SecureCRT解決中文亂碼

下載地址 https://xclient.info/s/navicat-premium.html#versions SecureCRT解決中文亂碼問題 在設置中設置為utf-8之后&#xff0c;還需要 $ sudo vi /etc/profile $打開文件&#xff0c;最后一行添加export LANGzh_CN.UTF-8

音視頻之使用sonic.cpp實現音頻倍速播放功能

sonic.cpp 是一個音頻處理庫&#xff0c;可以實現倍速播放。 如果單純通過修改pcm的采樣率來實現音頻倍速播放的話&#xff0c;就會出現聲音變調的情況。 以下是通過采集windows 虛擬聲卡獲取到的音頻數據&#xff0c; 我的聲卡采樣率是44100次/秒&#xff0c;audio_buffer_si…

SecurtCRT連接服務器自動斷開

mac Terminal-->Anti-idle-->send protocol NO-OP 60勾中

位圖原理、代碼實現及應用實例

位圖的原理&#xff1a; 在位圖中采用比特位表示對應的元素存在或者不存在 0&#xff1a;不存在 1&#xff1a;存在例如一個int整數有32個比特位可以表示0-31個整數。 再舉一個例子 存入的數字為8988 首先&#xff1a; 8988/32 280 其次&#xff1a; 8988%32 28 再來一個例…

通過修改注冊表,實現網頁鏈接中的私有協議啟用本地exe進程

私有協議為 coffeeclass://xxxxxx.mp4 注冊表如下 Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\coffeeclass] "coffeeClass Protocol" "URL Protocol"""[HKEY_CLASSES_ROOT\coffeeclass\DefaultIcon] "D:\\Program Files (x…

布隆過濾器的原理、應用場景和源碼分析實現

原理 布隆過濾器數據結構 布隆過濾器是一個 bit 向量或者說 bit 數組&#xff0c;長這樣&#xff1a; 如果我們要映射一個值到布隆過濾器中&#xff0c;我們需要使用多個不同的哈希函數生成多個哈希值&#xff0c;并對每個生成的哈希值指向的 bit 位置 1。 例如針對值 “baid…

判斷一個數字是否存在于某一個數據之中

哈希表 這個沒啥說的&#xff0c;后面補充 位圖 https://blog.csdn.net/csdn_kou/article/details/95337121 布隆過濾器 哈希表位圖 https://blog.csdn.net/csdn_kou/article/details/95371085

根據語句自動生成正則表達式

自動生成 http://www.txt2re.com 速查手冊 https://www.jb51.net/shouce/jquery/regexp.html

免密登錄堡壘機和服務器

免密登錄堡壘機 安裝oathtool和sshpass 這兩個文件安裝比較耗費時間&#xff01; brew install oath-toolkit brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb免密登錄堡壘機 書寫shell腳本 #!/usr/bin/env bash …

mysql建表sql

mysql建表 文章目錄mysql建表mysql學生表插入數據建表&#xff0c;學生和idgroup byinner joinmysql學生表 CREATE TABLE courses ( id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 自增id, student VARCHAR(255) DEFAULT NULL COMMENT 學生, class VARCHAR(255) DEFAU…

Effective C++學習第一天

1&#xff1a;區分C中的術語聲明、定義、初始化的概念聲明&#xff08;declaration&#xff09;&#xff1a;告訴編譯器某個東西的名稱和類型&#xff0c;但略去其他細節&#xff08;可以出現多次&#xff0c;編譯器不分配內存&#xff09;。定義&#xff08;definition&#x…

Redis運維和開發學習筆記(1) Redis簡介

文章目錄Redis的特性速度快持久化多種數據結構主從復制高可用和分布式典型的應用場景Redis啟動和可執行文件Redis可執行文件說明啟動方式驗證redisredis常用配置redis數據結構和內部編碼Redis是單線程&#xff0c;不會同時執行兩條命令哈希慢查詢pipelineRedis的特性 速度快 …

Effective C++學習第二天

1&#xff1a;確保對象被使用前已先被初始化&#xff0c;讀取未初始化的值會造成不明確的行為&#xff0c;可能導致程序終止運行或者其他不可預期的現象&#xff1b;在C中&#xff0c;當你使用C part of C(C中C語言部分的內容&#xff09;且初始化可能導致運行期成本&#xff0…

Redis運維和開發學習筆記(3)redis搭建集群

Redis運維和開發學習筆記(3)redis搭建集群 文章目錄Redis運維和開發學習筆記(3)redis搭建集群Redis集群搭建Redis集群搭建 cp /etc/redis.d/redistest_7001.conf /etc/redis.d/redistest_XXXX.conf :%s/7001/xxxx/g 配置文件內容&#xff1a;cluster-enabled yes ############…

Effective C++學習第三天

1&#xff1a;為多態基類聲明virtual析構函數當我們創建一個base class指針指向新生成的derived class時&#xff0c;當刪除基類指針時&#xff0c;如果base class是一個non-virtual析構函數時&#xff0c;實際執行的結果通常是derived class中的base成分被銷毀&#xff0c;der…

linux創建指定大小的文件

一、生成文件大小和實際占空間大小一樣的文件 dd if/dev/zero ofname.file bs1M count1 文件名稱name.file bs1M表示每一次讀寫1M數據&#xff0c;count50表示讀寫 50次&#xff0c;這樣就指定了生成文件的大小為50M。 二、生成文件大小固定&#xff0c;但實際不占空間命令 …

Effective C++學習第四天

條款11&#xff1a;在operator中處理自我賦值的現象雖然我們在平時可能不會出現顯示自我賦值的現象&#xff0c;當加入指針或者引用時&#xff0c;可能會出現不同的指針或引用指向同一對象&#xff08;對象的不同別名&#xff09;&#xff0c;這時候我們就得考慮對象是否是同一…

Effective C++學習第五天

條款14&#xff1a;在資源管理類中小心copy行為當我們深入理解“資源取得時機是初始化時機&#xff08;RAII&#xff09;”概念&#xff0c;并以此作為“資源管理類”的核心時&#xff0c;我們可能會遇到將RAII對象復制的情況&#xff0c;一般有兩種情況處理這個現象&#xff1…

Redis運維和開發學習筆記(2) redis持久化

Redis運維和開發學習筆記(2) redis持久化 文章目錄Redis運維和開發學習筆記(2) redis持久化持久化持久化方式一:RDB觸發~~的三種~~方式1. save命令2. bgsave配置觸發機制RDB 總結持久化方式二:AOFAOF的三種策略三種策略的優缺點AOF重寫機制持久化 redis將所有數據保存在內存中&…