用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.mzph.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将所有数据保存在内存中&…