当前位置: 首页 > news >正文

Python搭建http文件服务器实现手机电脑文件传输功能

第一种代码的界面如下:(有缺点,中文乱码)

# !/usr/bin/env python3
# -*- coding:utf-8 _*-"""Simple HTTP Server With Upload.
python -V3.6
This module builds on http.server by implementing the standard GET
and HEAD requests in a fairly straightforward manner.
"""__version__ = "0.1"
__all__ = ["SimpleHTTPRequestHandler"]
__author__ = "清纯世纪"
__home_page__ = "https://blog.csdn.net/qq_45100200/article/details/132343498"import os
import posixpath
import http.server
import socketserver
import urllib.request, urllib.parse, urllib.error
import html
import shutil
import mimetypes
import re
import argparse
import base64from io import BytesIOclass SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler):"""Simple HTTP request handler with GET/HEAD/POST commands.This serves files from the current directory and any of itssubdirectories.  The MIME type for files is determined bycalling the .guess_type() method. And can reveive file uploadedby client.The GET/HEAD/POST requests are identical except that the HEADrequest omits the actual contents of the file."""server_version = "SimpleHTTPWithUpload/" + __version__def do_GET(self):"""Serve a GET request."""f = self.send_head()if f:self.copyfile(f, self.wfile)f.close()def do_HEAD(self):"""Serve a HEAD request."""f = self.send_head()if f:f.close()def do_POST(self):"""Serve a POST request."""r, info = self.deal_post_data()print((r, info, "by: ", self.client_address))f = BytesIO()f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(b"<html>\n<title>Upload Result Page</title>\n")f.write(b"<body>\n<h2>Upload Result Page</h2>\n")f.write(b"<hr>\n")if r:f.write(b"<strong>Success:</strong>")else:f.write(b"<strong>Failed:</strong>")f.write(info.encode())f.write(("<br><a href=\"%s\">back</a>" % self.headers['referer']).encode())f.write(b"<hr><small>Powered By: bones7456, check new version at ")f.write(b"<a href=\"https://gist.github.com/UniIsland/3346170\">")f.write(b"here</a>.</small></body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()if f:self.copyfile(f, self.wfile)f.close()def deal_post_data(self):uploaded_files = []content_type = self.headers['content-type']if not content_type:return (False, "Content-Type header doesn't contain boundary")boundary = content_type.split("=")[1].encode()remainbytes = int(self.headers['content-length'])line = self.rfile.readline()remainbytes -= len(line)if not boundary in line:return (False, "Content NOT begin with boundary")while remainbytes > 0:line = self.rfile.readline()remainbytes -= len(line)fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line.decode())if not fn:return (False, "Can't find out file name...")path = self.translate_path(self.path)fn = os.path.join(path, fn[0])line = self.rfile.readline()remainbytes -= len(line)line = self.rfile.readline()remainbytes -= len(line)try:out = open(fn, 'wb')except IOError:return (False, "Can't create file to write, do you have permission to write?")else:with out:preline = self.rfile.readline()remainbytes -= len(preline)while remainbytes > 0:line = self.rfile.readline()remainbytes -= len(line)if boundary in line:preline = preline[0:-1]if preline.endswith(b'\r'):preline = preline[0:-1]out.write(preline)uploaded_files.append(fn)breakelse:out.write(preline)preline = linereturn (True, "File '%s' upload success!" % ",".join(uploaded_files))def send_head(self):"""Common code for GET and HEAD commands.This sends the response code and MIME headers.Return value is either a file object (which has to be copiedto the outputfile by the caller unless the command was HEAD,and must be closed by the caller under all circumstances), orNone, in which case the caller has nothing further to do."""path = self.translate_path(self.path)f = Noneif os.path.isdir(path):if not self.path.endswith('/'):# redirect browser - doing basically what apache doesself.send_response(301)self.send_header("Location", self.path + "/")self.end_headers()return Nonefor index in "index.html", "index.htm":index = os.path.join(path, index)if os.path.exists(index):path = indexbreakelse:return self.list_directory(path)ctype = self.guess_type(path)try:# Always read in binary mode. Opening files in text mode may cause# newline translations, making the actual size of the content# transmitted *less* than the content-length!f = open(path, 'rb')except IOError:self.send_error(404, "File not found")return Noneself.send_response(200)self.send_header("Content-type", ctype)fs = os.fstat(f.fileno())self.send_header("Content-Length", str(fs[6]))self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))self.end_headers()return fdef list_directory(self, path):"""Helper to produce a directory listing (absent index.html).Return value is either a file object, or None (indicating anerror).  In either case, the headers are sent, making theinterface the same as for send_head()."""try:list = os.listdir(path)except os.error:self.send_error(404, "No permission to list directory")return Nonelist.sort(key=lambda a: a.lower())f = BytesIO()displaypath = html.escape(urllib.parse.unquote(self.path))f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(("<html>\n<title>Directory listing for %s</title>\n" % displaypath).encode())f.write(b'<style type="text/css">\n')f.write(b'a { text-decoration: none; }\n')f.write(b'a:link { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:visited { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:active { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:hover { text-decoration: none; font-weight: bold; color: #ff0000; }\n')f.write(b'</style>\n')f.write(("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath).encode())f.write(b"<hr>\n")f.write(b"<form ENCTYPE=\"multipart/form-data\" method=\"post\">")f.write(b"<input name=\"file\" type=\"file\" multiple/>")f.write(b"<input type=\"submit\" value=\"upload\"/></form>\n")f.write(b"<hr>\n")f.write(b'<a href="../"><img src="https://img-blog.csdnimg.cn/2022010703250844034.gif" alt="[PARENTDIR]" width="24" height="24">&nbsp;&nbsp;&nbsp;Parent Directory</a><br />\n')for name in list:dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANdGLrc/jAuQaulQwYBuv9cFnFfSYoPWXoq2qgrALsTYN+4QOg6veFAG2FIdMCCNgvBiAxWlq8mUseUBqGMoxWArW1xXYXWGv59b+WxNH1GV9vsNvd9jsMhxLw+70gAADs='fullname = os.path.join(path, name)displayname = linkname = name# Append / for directories or @ for symbolic linksif os.path.isdir(fullname):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///+jNlr+/v6KXfm5SG2lPGjc3NwAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAIALAAAAAAYABgAAANjKLrc/jDKSau9WJbN9y1BKIZFVQzjOHRdsw1wDIMpyYAFke9ELa4Lmm9IWBkUwqHPiFQSmYKkU1U4Rqe1YrWJTUGlWK0VjP12R2Jubx1guwPQqGxOj22DrLzeujD4/4CBgAoJADs='displayname = name + "/"linkname = name + "/"if os.path.islink(fullname):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AJaWlpqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8LCwsPDw8bGxtDQ0NTU1NXV1dbW1tfX19jY2Nra2tzc3N3d3eDg4OHh4eLi4uPj4+Tk5OXl5efn5+np6erq6uvr6+zs7O7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pr6+vv7+/39/f7+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wCZCBxIsKDBgwgLrsigwUXChEVGYNBwIYKIJA8LFunwocKGDA8ieMg4kAiHDxRmCGyhIAEKkhtR2iCYYYEAkiNQ3ijYIQGAjDkuVFBJsIcBAhcyttCgoSCQBQcUFMn44gIFEiwE/oAqIAfJIREeQLDAZIeCAwO8IuQRowYSIxQgBFhAoQBatQaFiLCQoQIFCxEMREUwoAEPhEA0dMQwQSwCIEFYpKCR8IfiCjWYgJCr4AhJyx13CFRhQYECGBmRcKwgmmAEBCsyltBQQUfBGwUG4MjoYMOIgjsSIJBAskGGEAR3IEhw4AdJExIeyBCIY/kBHySZLNEwgcGGDQYQNBbPLpAIBgULEhB4AIQ8wRMFBIhQ4j4gADs='displayname = name + "@"if name.endswith(('.bmp', '.gif', '.jpg', '.png')):dirimage = nameif name.endswith(('.avi', '.mpg')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANvGLrc/jAuQqu99BEh8OXE4GzdYJ4mQIZjNXAwp7oj+MbyKjY6ntstyg03E9ZKPoEKyLMll6UgAUCtVi07xspTYWptqBOUxXM9scfQ2Ttx+sbZifmNbiLpbEUPHy1TrIB1Xx1cFHkBW4VODmGNjQ4JADs='if name.endswith(('.idx', '.srt', '.sub')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AAAbDiAfDSoqHjQlADs+J3sxJ0BALERHMk5LN1pSPUZHRk9NQU1OR05ZUFBRRFVXTVdYTVtVQFlVRFtbSF5bTVZWUltbUFlZVFtcVlxdWl5eWl1gWmBiV2FiXWNhXGRjXWlpYmtqZ2xtZmxsaG5ubHJva3Jzb3J0bHN0b3Z5dHd8eXh4dX18dXx/dnt8e31+eahMP4JdWIdnZox4cpVoYKJkXrxqablwcNA6Otg7O/8AAPwHB/0GBvgODvsMDPMbG/ceHvkSEuYqKvYqKvU2NvM6OvQ6OsFQUNVbW8N4eNd0duNeXu9aWvFUVOVqau1jY+1mZu5mZuh5eYSFgIWGgYaFgIiGgYqKiY6LioyMiY2NiYyMio2OiI6OjZCSjZSQi5OSkJGUkpSVk5WVlJWVlZiZlpiZmJ6emp2dnZSko6GhnKGhoKOjoaKnoqSkpKSmpKWmpaampqqrqKurqKqrqq2sqq6urrSyrrCwsLa3tb63tbi4t7q6ur+/vsCbm96Li9iUlMqursmwr9KwsN69veSCguiMjOiOjuaQkOWVleaXmOGfn+aYmOaamuebm+adneecnOeenuiQkOWgoOWsrOasrOWxseW2tue3t+e8vOi+vsHBwcfHx8jIxs7Mx8nJyMvLy8zMy83NzM7Pzs/Pz9PR0dTU1NXV1dXW1tbW1tfX19bb29jY2NnZ2djb29ra2tvb2tvb29za2tzc3N3d3d7e3t/f3+bCwufDw+fGxuTJyejCwujHx+nHx+vPz+rT0+rU1OrX1+vX1+rY2Ojf3+Hh4eLi4uPj4+Hn5+Tk5OXl5ebm5ufn5+nn5+jo6Onp6erp6evr6+zs7PDn5/Dq6vDt7fHv7/Lu7vPu7vPv7/Dw8PHx8fLy8vPz8/Tx8fbz8/T09PX19fX39/b29vj39/j4+Pn4+Pn5+fr5+fr6+vv7+/z7+/z8/P39/f7+/v/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wDhCRxIsKDBgwgTZis00F27hAbRNSpSaSC7ZM6ePQsXjdmzZekKUpOio0lBVShjJXvYjp07gsEm/dLhqKC2aNG2LesES13BXJTg4dLBi2C7kPDSyQFTRY26c8akZbolkJGOaQTZFTO2LA8KCCA+zDFTp4aggVCCmCtYrJUxNiI4nAjh4o2HGW1CrhvCxGC5cOVqvcCgQQUWGRtanOkG75qOQwXbhWvZ7lOZMIGSsJjihY5AYTowFWRnipUtT6BGWIARY8IXPc1eXtIxrKC7cqJCjdJCIcIBAwRoaLqU6IkRHthGnwPzoEGKDBISMHDAZWAvHUTWjaa1J42NAgAELMBAMGCNwHbWekQxqA4VMkBKSokZE8AKtHLpjuHxo0OSQXfuLKJIOHdc0IECFaxgQivpxHGDDpYc9McS5oBTAhxUbNHFFX2I4Q4fR+iwi0GPCCGLK6rYgQYJWZDhBil7cMMJDjpAAg85L8ETCRDVqAONMuGMA0446rDjEzzi5KDDD4j48g48huxAyCqtODNZOeWcM85DAxEDzDcE+YDEK5u0EostbZ2SyizsQASPE4PAo4466TxVZzptuqmLN266GRAAOw=='if name.endswith('.iso'):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AKysrLGxsbe3t7i4uLm5uLm5ubq6ury8vL29vb6+vry+wb2+wKfeu7XGsbjNtr3UprnVqbbcvqjOzKTM0KbdwKvX2anZ1b/CxbTbw63R5LHS5b3T5dexrtuxrty+p+KvpOCxo8bLnsvJotjAptTPs9HRtcDAwMHBwcLCwsPDw8PCxMLDxsTDwsTEw8TExMXFxcbGxsfHx8jIyMnJycrJysrKysvLy87Ly8zMzM3Nzc7Ozs/PzsDe3NDQ0NHR0dLR0NLS0tPT09TU1NXV1dXW1tbW1tfX19HZ0dLb0NjV1NrW1djY2NnZ2dra2t3a2tzc3N3d3d7e3d/f3t/f38HU5cPf6sff68/e69Pf6sDi3Nng59zh5d7k5ujEw+nFxOnGxunIx+vLx+zNyePTy+Hf3+3Y0eDg3+Tg3+Dg4OHh4uLi4eLi4uPj4uPj4+Hj5OPk4+Th4OTk4+Tk5OXl5OXl5eXm5ebl5Obm5ebm5ubn5ufn5ufn5+Lm6uXo6unj4+rl5Ojo5+jo6Onp6Onp6erq6erq6urr6+vr6uvr6+vs6+zp6e3r6uzs6+zs7O3t7e3u7e7u7e7u7u/v7u/v7+fv9ezu8e3u8PDp6fHr6/Dw8PHx8PHx8fLy8fLy8vPy8vPz8vPz8/Tz8/T08/T09PX19PX19fX29fb19Pb29vf39vf39/j49/j4+Pn4+Pn5+Pn5+fr6+fr6+vv7+vv7+/z8+/z8/P39/P39/f7+/f7+/v7//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wB3CRxIsKBBg4hi6GCyBs+eQIH2PJSIB82QGYgKDnqBowmeRpEiTSo0qVGmSI3oGJkxSOOLGkXkIJpkBEEQHzagZEq5siXBjTOGtJnpwweKBFCE7FTJ0mXQoZH2TIGCh4kjR4jkFGn684UMIXIGTWkSpQ0bOTIbaa3hc+BGGUSeFIkyhxCkT6hKDaKztq3AQS5m3EgSZw4gRplIvbq1KxIUI2w1umDBAQycPIQkgVo1K9etWXSARP6pooGID1/+POKEKtatXLFSfQLCdWChBRIYPPAgBpMpVrV20WIFKpMUF4UKElKwIYOFCCTKKCrUSBWsUpkY3WmR/KcLN1quVPLJgmTRrViBPHlyJAgPDL+7BsW4AyhRJUpcQO3S1YePpUN62FHbXy/sUYgkobQiCSKvnHIED1ZgscUb72l0gh6OsCYLLY60QcYYJWBQgQZUXEBIQYWYYAYnitmSCy2ldHJJGCNAQMEEK3TnVgo5jMJZLra8UoomjfjRBQghOEADfIW88AIdtdyCSyyocMJeHWd40cEPA+4SSGA+TLJLLauAIkkhesgRhxJOLCHDHgXhwVETbTjCiiuiSHIIIGo8UYghTcyAR0GgyDCAAAYMEMAJO/QwAwEAFHCAAQXIMMpBmzhSyCCD4JHGFA0FMkghMxEUEAA7'# Note: a link to a directory displays with @ and links with /f.write(('<a href="%s"><img src="%s" width="24" height="24">&nbsp;&nbsp;&nbsp;%s</a><br />\n'% (urllib.parse.quote(linkname), dirimage, html.escape(displayname))).encode())f.write(b"<hr>\n</body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()return fdef translate_path(self, path):"""Translate a /-separated PATH to the local filename syntax.Components that mean special things to the local file system(e.g. drive or directory names) are ignored.  (XXX They shouldprobably be diagnosed.)"""# abandon query parameterspath = path.split('?', 1)[0]path = path.split('#', 1)[0]path = posixpath.normpath(urllib.parse.unquote(path))words = path.split('/')words = [_f for _f in words if _f]path = os.getcwd()for word in words:drive, word = os.path.splitdrive(word)head, word = os.path.split(word)if word in (os.curdir, os.pardir): continuepath = os.path.join(path, word)return pathdef copyfile(self, source, outputfile):"""Copy all data between two file objects.The SOURCE argument is a file object open for reading(or anything with a read() method) and the DESTINATIONargument is a file object open for writing (oranything with a write() method).The only reason for overriding this would be to changethe block size or perhaps to replace newlines by CRLF-- note however that this the default server uses thisto copy binary data as well."""shutil.copyfileobj(source, outputfile)def guess_type(self, path):"""Guess the type of a file.Argument is a PATH (a filename).Return value is a string of the form type/subtype,usable for a MIME Content-type header.The default implementation looks the file's extensionup in the table self.extensions_map, using application/octet-streamas a default; however it would be permissible (ifslow) to look inside the data to make a better guess."""base, ext = posixpath.splitext(path)if ext in self.extensions_map:return self.extensions_map[ext]ext = ext.lower()if ext in self.extensions_map:return self.extensions_map[ext]else:return self.extensions_map['']if not mimetypes.inited:mimetypes.init()  # try to read system mime.typesextensions_map = mimetypes.types_map.copy()extensions_map.update({'': 'application/octet-stream',  # Default'.py': 'text/plain','.c': 'text/plain','.h': 'text/plain',})def get_local_ip():import socket"""获取本机IP地址"""try:s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)s.connect(('8.8.8.8', 80))ip = s.getsockname()[0]finally:s.close()return ipif __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',help='Specify alternate bind address ''[default: all interfaces]')parser.add_argument('port', action='store',default=8000, type=int,nargs='?',help='Specify alternate port [default: 8000]')args = parser.parse_args()PORT = args.portBIND = args.bindHOST = BINDif HOST == '':HOST = 'localhost'Handler = SimpleHTTPRequestHandlerwith socketserver.TCPServer((BIND, PORT), Handler) as httpd:serve_message = "Serving HTTP on {host} port {port} (http://{host}:{port}/) ..."print(serve_message.format(host=HOST, port=PORT))print("请输入以下地址进行文件传输:http://{}:{}".format(get_local_ip(),PORT))httpd.serve_forever()

第二种代码的界面如下:

#!/usr/bin/env python3"""Simple HTTP Server With Upload.
python -V3.6
This module builds on http.server by implementing the standard GET
and HEAD requests in a fairly straightforward manner.
"""__version__ = "0.1"
__all__ = ["SimpleHTTPRequestHandler"]
__author__ = "清纯世纪"
__home_page__ = "https://blog.csdn.net/qq_45100200/article/details/132343498"import os, sys
import os.path, time
import posixpath
import http.server
import socketserver
import urllib.request, urllib.parse, urllib.error
import html
import shutil
import mimetypes
import re
import argparse
import base64from io import BytesIOdef fbytes(B):'Return the given bytes as a human friendly KB, MB, GB, or TB string'B = float(B)KB = float(1024)MB = float(KB ** 2)  # 1,048,576GB = float(KB ** 3)  # 1,073,741,824TB = float(KB ** 4)  # 1,099,511,627,776if B < KB:return '{0} {1}'.format(B, 'Bytes' if 0 == B > 1 else 'Byte')elif KB <= B < MB:return '{0:.2f} KB'.format(B / KB)elif MB <= B < GB:return '{0:.2f} MB'.format(B / MB)elif GB <= B < TB:return '{0:.2f} GB'.format(B / GB)elif TB <= B:return '{0:.2f} TB'.format(B / TB)class SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler):"""Simple HTTP request handler with GET/HEAD/POST commands.This serves files from the current directory and any of itssubdirectories.  The MIME type for files is determined bycalling the .guess_type() method. And can reveive file uploadedby client.The GET/HEAD/POST requests are identical except that the HEADrequest omits the actual contents of the file."""server_version = "SimpleHTTPWithUpload/" + __version__def do_GET(self):"""Serve a GET request."""f = self.send_head()if f:self.copyfile(f, self.wfile)f.close()def do_HEAD(self):"""Serve a HEAD request."""f = self.send_head()if f:f.close()def do_POST(self):"""Serve a POST request."""r, info = self.deal_post_data()print((r, info, "by: ", self.client_address))f = BytesIO()f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(b"<html>\n<title>Upload Result Page</title>\n")f.write(b'<style type="text/css">\n')f.write(b'* {font-family: Helvetica; font-size: 16px; }\n')f.write(b'a { text-decoration: none; }\n')f.write(b'</style>\n')f.write(b"<body>\n<h2>Upload Result Page</h2>\n")f.write(b"<hr>\n")if r:f.write(b"<strong>Success!</strong>")else:f.write(b"<strong>Failed!</strong>")f.write(info.encode())f.write(("<br><br><a href=\"%s\">" % self.headers['referer']).encode())f.write(b"<button>Back</button></a>\n")f.write(b"<hr><small>Powered By: bones7456<br>Check new version ")f.write(b"<a href=\"https://gist.github.com/UniIsland/3346170\" target=\"_blank\">")f.write(b"here</a>.</small></body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()if f:self.copyfile(f, self.wfile)f.close()def deal_post_data(self):uploaded_files = []content_type = self.headers['content-type']if not content_type:return (False, "Content-Type header doesn't contain boundary")boundary = content_type.split("=")[1].encode()remainbytes = int(self.headers['content-length'])line = self.rfile.readline()remainbytes -= len(line)if not boundary in line:return (False, "Content NOT begin with boundary")while remainbytes > 0:line = self.rfile.readline()remainbytes -= len(line)fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line.decode())if not fn:return (False, "Can't find out file name...")path = self.translate_path(self.path)fn = os.path.join(path, fn[0])line = self.rfile.readline()remainbytes -= len(line)line = self.rfile.readline()remainbytes -= len(line)try:out = open(fn, 'wb')except IOError:return (False, "<br><br>Can't create file to write.<br>Do you have permission to write?")else:with out:preline = self.rfile.readline()remainbytes -= len(preline)while remainbytes > 0:line = self.rfile.readline()remainbytes -= len(line)if boundary in line:preline = preline[0:-1]if preline.endswith(b'\r'):preline = preline[0:-1]out.write(preline)uploaded_files.append(fn)breakelse:out.write(preline)preline = linereturn (True, "<br><br>'%s'" % "'<br>'".join(uploaded_files))def send_head(self):"""Common code for GET and HEAD commands.This sends the response code and MIME headers.Return value is either a file object (which has to be copiedto the outputfile by the caller unless the command was HEAD,and must be closed by the caller under all circumstances), orNone, in which case the caller has nothing further to do."""path = self.translate_path(self.path)f = Noneif os.path.isdir(path):if not self.path.endswith('/'):# redirect browser - doing basically what apache doesself.send_response(301)self.send_header("Location", self.path + "/")self.end_headers()return Nonefor index in "index.html", "index.htm":index = os.path.join(path, index)if os.path.exists(index):path = indexbreakelse:return self.list_directory(path)ctype = self.guess_type(path)try:# Always read in binary mode. Opening files in text mode may cause# newline translations, making the actual size of the content# transmitted *less* than the content-length!f = open(path, 'rb')except IOError:self.send_error(404, "File not found")return Noneself.send_response(200)self.send_header("Content-type", ctype)fs = os.fstat(f.fileno())self.send_header("Content-Length", str(fs[6]))self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))self.end_headers()return fdef list_directory(self, path):"""Helper to produce a directory listing (absent index.html).Return value is either a file object, or None (indicating anerror).  In either case, the headers are sent, making theinterface the same as for send_head()."""try:list = os.listdir(path)except os.error:self.send_error(404, "No permission to list directory")return Noneenc = sys.getfilesystemencoding()list.sort(key=lambda a: a.lower())f = BytesIO()displaypath = html.escape(urllib.parse.unquote(self.path))f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(b'<html>\n')f.write(('<meta http-equiv="Content-Type" ''content="text/html; charset=%s">' % enc).encode(enc))f.write(("<title>Directory listing for %s</title>\n" % displaypath).encode(enc))f.write(b'<style type="text/css">\n')f.write(b'* {font-family: Helvetica; font-size: 16px; }\n')f.write(b'a { text-decoration: none; }\n')f.write(b'a:link { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:visited { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:active { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:hover { text-decoration: none; font-weight: bold; color: #ff0000; }\n')f.write(b'table {\n  border-collapse: separate;\n}\n')f.write(b'th, td {\n  padding:0px 10px;\n}\n')f.write(b'</style>\n')f.write(("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath).encode(enc))f.write(b"<hr>\n")f.write(b"<form ENCTYPE=\"multipart/form-data\" method=\"post\">")f.write(b"<input name=\"file\" type=\"file\" multiple/>")f.write(b"<input type=\"submit\" value=\"upload\"/></form>\n")f.write(b"<hr>\n")f.write(b'<table>\n')f.write(b'<tr><td><img src="data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANKGLrc/jBKNgIhM4rLcaZWd33KJnJkdaKZuXqTugYFeSpFTVpLnj86oM/n+DWGyCAuyUQymlDiMtrsUavP6xCizUB3NCW4Ny6bJwkAOw==" alt="[PARENTDIR]" width="24" height="24"></td><td><a href="../" >Parent Directory</a></td></tr>\n')for name in list:dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANdGLrc/jAuQaulQwYBuv9cFnFfSYoPWXoq2qgrALsTYN+4QOg6veFAG2FIdMCCNgvBiAxWlq8mUseUBqGMoxWArW1xXYXWGv59b+WxNH1GV9vsNvd9jsMhxLw+70gAADs='fullname = os.path.join(path, name)displayname = linkname = namefsize = fbytes(os.path.getsize(fullname))created_date = time.ctime(os.path.getctime(fullname))# Append / for directories or @ for symbolic linksif os.path.isdir(fullname):dirimage = 'data:image/png;base64,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'displayname = name + "/"linkname = name + "/"fsize = ''created_date = ''if os.path.islink(fullname):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AJaWlpqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8LCwsPDw8bGxtDQ0NTU1NXV1dbW1tfX19jY2Nra2tzc3N3d3eDg4OHh4eLi4uPj4+Tk5OXl5efn5+np6erq6uvr6+zs7O7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pr6+vv7+/39/f7+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wCZCBxIsKDBgwgLrsigwUXChEVGYNBwIYKIJA8LFunwocKGDA8ieMg4kAiHDxRmCGyhIAEKkhtR2iCYYYEAkiNQ3ijYIQGAjDkuVFBJsIcBAhcyttCgoSCQBQcUFMn44gIFEiwE/oAqIAfJIREeQLDAZIeCAwO8IuQRowYSIxQgBFhAoQBatQaFiLCQoQIFCxEMREUwoAEPhEA0dMQwQSwCIEFYpKCR8IfiCjWYgJCr4AhJyx13CFRhQYECGBmRcKwgmmAEBCsyltBQQUfBGwUG4MjoYMOIgjsSIJBAskGGEAR3IEhw4AdJExIeyBCIY/kBHySZLNEwgcGGDQYQNBbPLpAIBgULEhB4AIQ8wRMFBIhQ4j4gADs='displayname = name + "@"if name.endswith(('.bmp', '.gif', '.jpg', '.png')):dirimage = nameif name.endswith(('.avi', '.mpg')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANvGLrc/jAuQqu99BEh8OXE4GzdYJ4mQIZjNXAwp7oj+MbyKjY6ntstyg03E9ZKPoEKyLMll6UgAUCtVi07xspTYWptqBOUxXM9scfQ2Ttx+sbZifmNbiLpbEUPHy1TrIB1Xx1cFHkBW4VODmGNjQ4JADs='if name.endswith(('.idx', '.srt', '.sub')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AAAbDiAfDSoqHjQlADs+J3sxJ0BALERHMk5LN1pSPUZHRk9NQU1OR05ZUFBRRFVXTVdYTVtVQFlVRFtbSF5bTVZWUltbUFlZVFtcVlxdWl5eWl1gWmBiV2FiXWNhXGRjXWlpYmtqZ2xtZmxsaG5ubHJva3Jzb3J0bHN0b3Z5dHd8eXh4dX18dXx/dnt8e31+eahMP4JdWIdnZox4cpVoYKJkXrxqablwcNA6Otg7O/8AAPwHB/0GBvgODvsMDPMbG/ceHvkSEuYqKvYqKvU2NvM6OvQ6OsFQUNVbW8N4eNd0duNeXu9aWvFUVOVqau1jY+1mZu5mZuh5eYSFgIWGgYaFgIiGgYqKiY6LioyMiY2NiYyMio2OiI6OjZCSjZSQi5OSkJGUkpSVk5WVlJWVlZiZlpiZmJ6emp2dnZSko6GhnKGhoKOjoaKnoqSkpKSmpKWmpaampqqrqKurqKqrqq2sqq6urrSyrrCwsLa3tb63tbi4t7q6ur+/vsCbm96Li9iUlMqursmwr9KwsN69veSCguiMjOiOjuaQkOWVleaXmOGfn+aYmOaamuebm+adneecnOeenuiQkOWgoOWsrOasrOWxseW2tue3t+e8vOi+vsHBwcfHx8jIxs7Mx8nJyMvLy8zMy83NzM7Pzs/Pz9PR0dTU1NXV1dXW1tbW1tfX19bb29jY2NnZ2djb29ra2tvb2tvb29za2tzc3N3d3d7e3t/f3+bCwufDw+fGxuTJyejCwujHx+nHx+vPz+rT0+rU1OrX1+vX1+rY2Ojf3+Hh4eLi4uPj4+Hn5+Tk5OXl5ebm5ufn5+nn5+jo6Onp6erp6evr6+zs7PDn5/Dq6vDt7fHv7/Lu7vPu7vPv7/Dw8PHx8fLy8vPz8/Tx8fbz8/T09PX19fX39/b29vj39/j4+Pn4+Pn5+fr5+fr6+vv7+/z7+/z8/P39/f7+/v/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wDhCRxIsKDBgwgTZis00F27hAbRNSpSaSC7ZM6ePQsXjdmzZekKUpOio0lBVShjJXvYjp07gsEm/dLhqKC2aNG2LesES13BXJTg4dLBi2C7kPDSyQFTRY26c8akZbolkJGOaQTZFTO2LA8KCCA+zDFTp4aggVCCmCtYrJUxNiI4nAjh4o2HGW1CrhvCxGC5cOVqvcCgQQUWGRtanOkG75qOQwXbhWvZ7lOZMIGSsJjihY5AYTowFWRnipUtT6BGWIARY8IXPc1eXtIxrKC7cqJCjdJCIcIBAwRoaLqU6IkRHthGnwPzoEGKDBISMHDAZWAvHUTWjaa1J42NAgAELMBAMGCNwHbWekQxqA4VMkBKSokZE8AKtHLpjuHxo0OSQXfuLKJIOHdc0IECFaxgQivpxHGDDpYc9McS5oBTAhxUbNHFFX2I4Q4fR+iwi0GPCCGLK6rYgQYJWZDhBil7cMMJDjpAAg85L8ETCRDVqAONMuGMA0446rDjEzzi5KDDD4j48g48huxAyCqtODNZOeWcM85DAxEDzDcE+YDEK5u0EostbZ2SyizsQASPE4PAo4466TxVZzptuqmLN266GRAAOw=='if name.endswith('.iso'):dirimage = 'data:image/png;base64,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'# Note: a link to a directory displays with @ and links with /f.write(('<tr><td><img src="%s" width="24" height="24"></td><td><a href="%s">%s</a></td><td style="text-align:right; font-weight: bold; color:#FF0000">%s</td><td style="text-align:right; font-weight: bold;">%s</td></tr>\n'% (dirimage, urllib.parse.quote(linkname), html.escape(displayname), fsize,created_date)).encode(enc))f.write(b"</table><hr>\n</body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()return fdef translate_path(self, path):"""Translate a /-separated PATH to the local filename syntax.Components that mean special things to the local file system(e.g. drive or directory names) are ignored.  (XXX They shouldprobably be diagnosed.)"""# abandon query parameterspath = path.split('?', 1)[0]path = path.split('#', 1)[0]path = posixpath.normpath(urllib.parse.unquote(path))words = path.split('/')words = [_f for _f in words if _f]path = os.getcwd()for word in words:drive, word = os.path.splitdrive(word)head, word = os.path.split(word)if word in (os.curdir, os.pardir): continuepath = os.path.join(path, word)return pathdef copyfile(self, source, outputfile):"""Copy all data between two file objects.The SOURCE argument is a file object open for reading(or anything with a read() method) and the DESTINATIONargument is a file object open for writing (oranything with a write() method).The only reason for overriding this would be to changethe block size or perhaps to replace newlines by CRLF-- note however that this the default server uses thisto copy binary data as well."""shutil.copyfileobj(source, outputfile)def guess_type(self, path):"""Guess the type of a file.Argument is a PATH (a filename).Return value is a string of the form type/subtype,usable for a MIME Content-type header.The default implementation looks the file's extensionup in the table self.extensions_map, using application/octet-streamas a default; however it would be permissible (ifslow) to look inside the data to make a better guess."""base, ext = posixpath.splitext(path)if ext in self.extensions_map:return self.extensions_map[ext]ext = ext.lower()if ext in self.extensions_map:return self.extensions_map[ext]else:return self.extensions_map['']if not mimetypes.inited:mimetypes.init()  # try to read system mime.typesextensions_map = mimetypes.types_map.copy()extensions_map.update({'': 'application/octet-stream',  # Default'.py': 'text/plain','.c': 'text/plain','.h': 'text/plain',})def get_local_ip():import socket"""获取本机IP地址"""try:s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)s.connect(('8.8.8.8', 80))ip = s.getsockname()[0]finally:s.close()return ipif __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',help='Specify alternate bind address ''[default: all interfaces]')parser.add_argument('port', action='store',default=8000, type=int,nargs='?',help='Specify alternate port [default: 8000]')args = parser.parse_args()PORT = args.portBIND = args.bindHOST = BINDif HOST == '':HOST = 'localhost'Handler = SimpleHTTPRequestHandlerwith socketserver.TCPServer((BIND, PORT), Handler) as httpd:serve_message = "Serving HTTP on {host} port {port} (http://{host}:{port}/) ..."print(serve_message.format(host=HOST, port=PORT))print("请输入以下地址进行文件传输:http://{}:{}".format(get_local_ip(), PORT))httpd.serve_forever()

最后在来一个传输进度条显示的吧,基于第二个代码,第一个照着改就行。(也有缺点,我这使用后好像传输速度变慢了,可以自行测试验证):

#!/usr/bin/env python3"""Simple HTTP Server With Upload.
python -V3.6
This module builds on http.server by implementing the standard GET
and HEAD requests in a fairly straightforward manner.
"""__version__ = "0.1"
__all__ = ["SimpleHTTPRequestHandler"]
__author__ = "清纯世纪"
__home_page__ = "https://blog.csdn.net/qq_45100200/article/details/132343498"import os, sys
import os.path, time
import posixpath
import http.server
import socketserver
import urllib.request, urllib.parse, urllib.error
import html
import shutil
import mimetypes
import re
import argparse
import base64
from tqdm import tqdm
from io import BytesIOdef fbytes(B):'Return the given bytes as a human friendly KB, MB, GB, or TB string'B = float(B)KB = float(1024)MB = float(KB ** 2)  # 1,048,576GB = float(KB ** 3)  # 1,073,741,824TB = float(KB ** 4)  # 1,099,511,627,776if B < KB:return '{0} {1}'.format(B, 'Bytes' if 0 == B > 1 else 'Byte')elif KB <= B < MB:return '{0:.2f} KB'.format(B / KB)elif MB <= B < GB:return '{0:.2f} MB'.format(B / MB)elif GB <= B < TB:return '{0:.2f} GB'.format(B / GB)elif TB <= B:return '{0:.2f} TB'.format(B / TB)class SimpleHTTPRequestHandler(http.server.BaseHTTPRequestHandler):"""Simple HTTP request handler with GET/HEAD/POST commands.This serves files from the current directory and any of itssubdirectories.  The MIME type for files is determined bycalling the .guess_type() method. And can reveive file uploadedby client.The GET/HEAD/POST requests are identical except that the HEADrequest omits the actual contents of the file."""server_version = "SimpleHTTPWithUpload/" + __version__def do_GET(self):"""Serve a GET request."""f = self.send_head()if f:self.copyfile(f, self.wfile)f.close()def do_HEAD(self):"""Serve a HEAD request."""f = self.send_head()if f:f.close()def do_POST(self):"""Serve a POST request."""r, info = self.deal_post_data()print((r, info, "by: ", self.client_address))f = BytesIO()f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(b"<html>\n<title>Upload Result Page</title>\n")f.write(b'<style type="text/css">\n')f.write(b'* {font-family: Helvetica; font-size: 16px; }\n')f.write(b'a { text-decoration: none; }\n')f.write(b'</style>\n')f.write(b"<body>\n<h2>Upload Result Page</h2>\n")f.write(b"<hr>\n")if r:f.write(b"<strong>Success!</strong>")else:f.write(b"<strong>Failed!</strong>")f.write(info.encode())f.write(("<br><br><a href=\"%s\">" % self.headers['referer']).encode())f.write(b"<button>Back</button></a>\n")f.write(b"<hr><small>Powered By: bones7456<br>Check new version ")f.write(b"<a href=\"https://gist.github.com/UniIsland/3346170\" target=\"_blank\">")f.write(b"here</a>.</small></body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()if f:self.copyfile(f, self.wfile)f.close()def deal_post_data(self):uploaded_files = []content_type = self.headers['content-type']if not content_type:return (False, "Content-Type header doesn't contain boundary")boundary = content_type.split("=")[1].encode()remainbytes = int(self.headers['content-length'])line = self.rfile.readline()remainbytes -= len(line)if not boundary in line:return (False, "Content NOT begin with boundary")while remainbytes > 0:line = self.rfile.readline()remainbytes -= len(line)fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line.decode())if not fn:return (False, "Can't find out file name...")path = self.translate_path(self.path)fn = os.path.join(path, fn[0])line = self.rfile.readline()remainbytes -= len(line)line = self.rfile.readline()remainbytes -= len(line)try:out = open(fn, 'wb')except IOError:return (False, "<br><br>Can't create file to write.<br>Do you have permission to write?")else:with out:pbar = tqdm()  # 建立一个监听器preline = self.rfile.readline()remainbytes -= len(preline)total_size = remainbyteswhile remainbytes > 0:pbar.set_description("Processing {:.2f} %".format((1-(remainbytes/total_size))*100)) # 进度条line = self.rfile.readline()remainbytes -= len(line)if boundary in line:preline = preline[0:-1]if preline.endswith(b'\r'):preline = preline[0:-1]out.write(preline)uploaded_files.append(fn)breakelse:out.write(preline)preline = linereturn (True, "<br><br>'%s'" % "'<br>'".join(uploaded_files))def send_head(self):"""Common code for GET and HEAD commands.This sends the response code and MIME headers.Return value is either a file object (which has to be copiedto the outputfile by the caller unless the command was HEAD,and must be closed by the caller under all circumstances), orNone, in which case the caller has nothing further to do."""path = self.translate_path(self.path)f = Noneif os.path.isdir(path):if not self.path.endswith('/'):# redirect browser - doing basically what apache doesself.send_response(301)self.send_header("Location", self.path + "/")self.end_headers()return Nonefor index in "index.html", "index.htm":index = os.path.join(path, index)if os.path.exists(index):path = indexbreakelse:return self.list_directory(path)ctype = self.guess_type(path)try:# Always read in binary mode. Opening files in text mode may cause# newline translations, making the actual size of the content# transmitted *less* than the content-length!f = open(path, 'rb')except IOError:self.send_error(404, "File not found")return Noneself.send_response(200)self.send_header("Content-type", ctype)fs = os.fstat(f.fileno())self.send_header("Content-Length", str(fs[6]))self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))self.end_headers()return fdef list_directory(self, path):"""Helper to produce a directory listing (absent index.html).Return value is either a file object, or None (indicating anerror).  In either case, the headers are sent, making theinterface the same as for send_head()."""try:list = os.listdir(path)except os.error:self.send_error(404, "No permission to list directory")return Noneenc = sys.getfilesystemencoding()list.sort(key=lambda a: a.lower())f = BytesIO()displaypath = html.escape(urllib.parse.unquote(self.path))f.write(b'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')f.write(b'<html>\n')f.write(('<meta http-equiv="Content-Type" ''content="text/html; charset=%s">' % enc).encode(enc))f.write(("<title>Directory listing for %s</title>\n" % displaypath).encode(enc))f.write(b'<style type="text/css">\n')f.write(b'* {font-family: Helvetica; font-size: 16px; }\n')f.write(b'a { text-decoration: none; }\n')f.write(b'a:link { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:visited { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:active { text-decoration: none; font-weight: bold; color: #0000ff; }\n')f.write(b'a:hover { text-decoration: none; font-weight: bold; color: #ff0000; }\n')f.write(b'table {\n  border-collapse: separate;\n}\n')f.write(b'th, td {\n  padding:0px 10px;\n}\n')f.write(b'</style>\n')f.write(("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath).encode(enc))f.write(b"<hr>\n")f.write(b"<form ENCTYPE=\"multipart/form-data\" method=\"post\">")f.write(b"<input name=\"file\" type=\"file\" multiple/>")f.write(b"<input type=\"submit\" value=\"upload\"/></form>\n")f.write(b"<hr>\n")f.write(b'<table>\n')f.write(b'<tr><td><img src="data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANKGLrc/jBKNgIhM4rLcaZWd33KJnJkdaKZuXqTugYFeSpFTVpLnj86oM/n+DWGyCAuyUQymlDiMtrsUavP6xCizUB3NCW4Ny6bJwkAOw==" alt="[PARENTDIR]" width="24" height="24"></td><td><a href="../" >Parent Directory</a></td></tr>\n')for name in list:dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANdGLrc/jAuQaulQwYBuv9cFnFfSYoPWXoq2qgrALsTYN+4QOg6veFAG2FIdMCCNgvBiAxWlq8mUseUBqGMoxWArW1xXYXWGv59b+WxNH1GV9vsNvd9jsMhxLw+70gAADs='fullname = os.path.join(path, name)displayname = linkname = namefsize = fbytes(os.path.getsize(fullname))created_date = time.ctime(os.path.getctime(fullname))# Append / for directories or @ for symbolic linksif os.path.isdir(fullname):dirimage = 'data:image/png;base64,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'displayname = name + "/"linkname = name + "/"fsize = ''created_date = ''if os.path.islink(fullname):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AJaWlpqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8LCwsPDw8bGxtDQ0NTU1NXV1dbW1tfX19jY2Nra2tzc3N3d3eDg4OHh4eLi4uPj4+Tk5OXl5efn5+np6erq6uvr6+zs7O7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pr6+vv7+/39/f7+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wCZCBxIsKDBgwgLrsigwUXChEVGYNBwIYKIJA8LFunwocKGDA8ieMg4kAiHDxRmCGyhIAEKkhtR2iCYYYEAkiNQ3ijYIQGAjDkuVFBJsIcBAhcyttCgoSCQBQcUFMn44gIFEiwE/oAqIAfJIREeQLDAZIeCAwO8IuQRowYSIxQgBFhAoQBatQaFiLCQoQIFCxEMREUwoAEPhEA0dMQwQSwCIEFYpKCR8IfiCjWYgJCr4AhJyx13CFRhQYECGBmRcKwgmmAEBCsyltBQQUfBGwUG4MjoYMOIgjsSIJBAskGGEAR3IEhw4AdJExIeyBCIY/kBHySZLNEwgcGGDQYQNBbPLpAIBgULEhB4AIQ8wRMFBIhQ4j4gADs='displayname = name + "@"if name.endswith(('.bmp', '.gif', '.jpg', '.png')):dirimage = nameif name.endswith(('.avi', '.mpg')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAMIAAP///7+/v7u7u1ZWVTc3NwAAAAAAAAAAACH+RFRoaXMgaWNvbiBpcyBpbiB0aGUgcHVibGljIGRvbWFpbi4gMTk5NSBLZXZpbiBIdWdoZXMsIGtldmluaEBlaXQuY29tACH5BAEAAAEALAAAAAAYABgAAANvGLrc/jAuQqu99BEh8OXE4GzdYJ4mQIZjNXAwp7oj+MbyKjY6ntstyg03E9ZKPoEKyLMll6UgAUCtVi07xspTYWptqBOUxXM9scfQ2Ttx+sbZifmNbiLpbEUPHy1TrIB1Xx1cFHkBW4VODmGNjQ4JADs='if name.endswith(('.idx', '.srt', '.sub')):dirimage = 'data:image/gif;base64,R0lGODlhGAAYAPf/AAAbDiAfDSoqHjQlADs+J3sxJ0BALERHMk5LN1pSPUZHRk9NQU1OR05ZUFBRRFVXTVdYTVtVQFlVRFtbSF5bTVZWUltbUFlZVFtcVlxdWl5eWl1gWmBiV2FiXWNhXGRjXWlpYmtqZ2xtZmxsaG5ubHJva3Jzb3J0bHN0b3Z5dHd8eXh4dX18dXx/dnt8e31+eahMP4JdWIdnZox4cpVoYKJkXrxqablwcNA6Otg7O/8AAPwHB/0GBvgODvsMDPMbG/ceHvkSEuYqKvYqKvU2NvM6OvQ6OsFQUNVbW8N4eNd0duNeXu9aWvFUVOVqau1jY+1mZu5mZuh5eYSFgIWGgYaFgIiGgYqKiY6LioyMiY2NiYyMio2OiI6OjZCSjZSQi5OSkJGUkpSVk5WVlJWVlZiZlpiZmJ6emp2dnZSko6GhnKGhoKOjoaKnoqSkpKSmpKWmpaampqqrqKurqKqrqq2sqq6urrSyrrCwsLa3tb63tbi4t7q6ur+/vsCbm96Li9iUlMqursmwr9KwsN69veSCguiMjOiOjuaQkOWVleaXmOGfn+aYmOaamuebm+adneecnOeenuiQkOWgoOWsrOasrOWxseW2tue3t+e8vOi+vsHBwcfHx8jIxs7Mx8nJyMvLy8zMy83NzM7Pzs/Pz9PR0dTU1NXV1dXW1tbW1tfX19bb29jY2NnZ2djb29ra2tvb2tvb29za2tzc3N3d3d7e3t/f3+bCwufDw+fGxuTJyejCwujHx+nHx+vPz+rT0+rU1OrX1+vX1+rY2Ojf3+Hh4eLi4uPj4+Hn5+Tk5OXl5ebm5ufn5+nn5+jo6Onp6erp6evr6+zs7PDn5/Dq6vDt7fHv7/Lu7vPu7vPv7/Dw8PHx8fLy8vPz8/Tx8fbz8/T09PX19fX39/b29vj39/j4+Pn4+Pn5+fr5+fr6+vv7+/z7+/z8/P39/f7+/v/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAYAAAI/wDhCRxIsKDBgwgTZis00F27hAbRNSpSaSC7ZM6ePQsXjdmzZekKUpOio0lBVShjJXvYjp07gsEm/dLhqKC2aNG2LesES13BXJTg4dLBi2C7kPDSyQFTRY26c8akZbolkJGOaQTZFTO2LA8KCCA+zDFTp4aggVCCmCtYrJUxNiI4nAjh4o2HGW1CrhvCxGC5cOVqvcCgQQUWGRtanOkG75qOQwXbhWvZ7lOZMIGSsJjihY5AYTowFWRnipUtT6BGWIARY8IXPc1eXtIxrKC7cqJCjdJCIcIBAwRoaLqU6IkRHthGnwPzoEGKDBISMHDAZWAvHUTWjaa1J42NAgAELMBAMGCNwHbWekQxqA4VMkBKSokZE8AKtHLpjuHxo0OSQXfuLKJIOHdc0IECFaxgQivpxHGDDpYc9McS5oBTAhxUbNHFFX2I4Q4fR+iwi0GPCCGLK6rYgQYJWZDhBil7cMMJDjpAAg85L8ETCRDVqAONMuGMA0446rDjEzzi5KDDD4j48g48huxAyCqtODNZOeWcM85DAxEDzDcE+YDEK5u0EostbZ2SyizsQASPE4PAo4466TxVZzptuqmLN266GRAAOw=='if name.endswith('.iso'):dirimage = 'data:image/png;base64,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'# Note: a link to a directory displays with @ and links with /f.write(('<tr><td><img src="%s" width="24" height="24"></td><td><a href="%s">%s</a></td><td style="text-align:right; font-weight: bold; color:#FF0000">%s</td><td style="text-align:right; font-weight: bold;">%s</td></tr>\n'% (dirimage, urllib.parse.quote(linkname), html.escape(displayname), fsize,created_date)).encode(enc))f.write(b"</table><hr>\n</body>\n</html>\n")length = f.tell()f.seek(0)self.send_response(200)self.send_header("Content-type", "text/html")self.send_header("Content-Length", str(length))self.end_headers()return fdef translate_path(self, path):"""Translate a /-separated PATH to the local filename syntax.Components that mean special things to the local file system(e.g. drive or directory names) are ignored.  (XXX They shouldprobably be diagnosed.)"""# abandon query parameterspath = path.split('?', 1)[0]path = path.split('#', 1)[0]path = posixpath.normpath(urllib.parse.unquote(path))words = path.split('/')words = [_f for _f in words if _f]path = os.getcwd()for word in words:drive, word = os.path.splitdrive(word)head, word = os.path.split(word)if word in (os.curdir, os.pardir): continuepath = os.path.join(path, word)return pathdef copyfile(self, source, outputfile):"""Copy all data between two file objects.The SOURCE argument is a file object open for reading(or anything with a read() method) and the DESTINATIONargument is a file object open for writing (oranything with a write() method).The only reason for overriding this would be to changethe block size or perhaps to replace newlines by CRLF-- note however that this the default server uses thisto copy binary data as well."""shutil.copyfileobj(source, outputfile)def guess_type(self, path):"""Guess the type of a file.Argument is a PATH (a filename).Return value is a string of the form type/subtype,usable for a MIME Content-type header.The default implementation looks the file's extensionup in the table self.extensions_map, using application/octet-streamas a default; however it would be permissible (ifslow) to look inside the data to make a better guess."""base, ext = posixpath.splitext(path)if ext in self.extensions_map:return self.extensions_map[ext]ext = ext.lower()if ext in self.extensions_map:return self.extensions_map[ext]else:return self.extensions_map['']if not mimetypes.inited:mimetypes.init()  # try to read system mime.typesextensions_map = mimetypes.types_map.copy()extensions_map.update({'': 'application/octet-stream',  # Default'.py': 'text/plain','.c': 'text/plain','.h': 'text/plain',})def get_local_ip():import socket"""获取本机IP地址"""try:s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)s.connect(('8.8.8.8', 80))ip = s.getsockname()[0]finally:s.close()return ipif __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('--bind', '-b', default='', metavar='ADDRESS',help='Specify alternate bind address ''[default: all interfaces]')parser.add_argument('port', action='store',default=8000, type=int,nargs='?',help='Specify alternate port [default: 8000]')args = parser.parse_args()PORT = args.portBIND = args.bindHOST = BINDif HOST == '':HOST = 'localhost'Handler = SimpleHTTPRequestHandlerwith socketserver.TCPServer((BIND, PORT), Handler) as httpd:serve_message = "Serving HTTP on {host} port {port} (http://{host}:{port}/) ..."print(serve_message.format(host=HOST, port=PORT))print("请输入以下地址进行文件传输:http://{}:{}".format(get_local_ip(), PORT))httpd.serve_forever()

相关文章:

Python搭建http文件服务器实现手机电脑文件传输功能

第一种代码的界面如下&#xff1a;&#xff08;有缺点&#xff0c;中文乱码&#xff09; # !/usr/bin/env python3 # -*- coding:utf-8 _*-"""Simple HTTP Server With Upload. python -V3.6 This module builds on http.server by implementing the standard G…...

微信小程序实现拖拽的小球

目录 前言 js 获取微信小程序中获取系统信息 触摸移动事件的处理函数 触摸结束事件的处理函数 用于监听页面滚动事件 全局参数 html CSS 前言 小程序开发提供了丰富的API和事件处理函数&#xff0c;使得开发者可以方便地实现各种交互功能。其中&#xff0c;拖拽功能…...

uniapp的逆地理编码 和地理编码

1.先打开高德地图api找到那个 地理编码 2.封装好我们的请求 3.逆地理编码 和地理编码 都是固定的 记住自己封装的请求 就可以了 这个 是固定的 方式 下面这个是固定的 可以复制过去 getlocation就是uniapp提供的 获取经纬度 然后 下面的 就是高德地图提供的 方法 要想使用我…...

在Centos环境中搭建Nginx环境

一、Nginx概念简介 Nginx是一个轻量级的高性能HTTP反向代理服务器&#xff0c;同时它也是一个通用类型的代理服务器&#xff0c;支持绝大部分协议&#xff0c;如TCP、UDP、SMTP、HTTPS等。 Nginx与redis相同&#xff0c;都是基于多路复用模型构建出的产物&#xff0c;因此它与R…...

20W IP网络吸顶喇叭 POE供电吸顶喇叭

SV-29852T 20W IP网络吸顶喇叭产品简介 产品用途&#xff1a; ◆室内豪华型吸顶喇叭一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用 ◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车场等&#xff1b;室内使用效果均佳。 产品特点&#xff…...

React 之 Suspense和lazy

一. Suspense 参考链接&#xff1a;https://react.docschina.org/reference/react/Suspense suspense&#xff1a;n. 焦虑、悬念 <Suspense> 允许你显示一个退路方案&#xff08;fallback&#xff09;直到它的所有子组件完成加载。 <Suspense fallback{<Loadin…...

Kafka中的 ISR 机制

ISR 是什么 ISR 的全称叫做&#xff1a; In-Sync Replicas &#xff08;同步副本集&#xff09;, 可以理解为和 leader 保持同步的所有副本的集合。ISR 动态维护了一个和 leader 副本保持同步副本集合&#xff0c;ISR 中的副本全部都和 leader 的数据保持同步。 设一个场景&a…...

01 Python 网络爬虫:爬虫技术的核心原理

不夸张地说&#xff0c;现在哪怕是初中生&#xff0c;只要花点儿时间、精力稍微按「网络爬虫」的开发步骤学习了解一下&#xff0c;也能把它玩得贼溜。 听起来感觉是很高大上的东西&#xff0c;但实际上并不复杂&#xff0c;也就是使用了某种编程语言按照一定步骤、规则主动通…...

【Rust】Rust学习 第十四章进一步认识 Cargo 和 Crates.io

本章会讨论 Cargo 其他一些更为高级的功能&#xff0c;我们将展示如何&#xff1a; 使用发布配置来自定义构建将库发布到 crates.io使用工作空间来组织更大的项目从 crates.io 安装二进制文件使用自定义的命令来扩展 Cargo Cargo 的功能不止本章所介绍的&#xff0c;关于其全…...

Android性能优化----执行时间优化

作者&#xff1a;lu人皆知 在APP做启动优化时&#xff0c;Application会做一些初始化的工作&#xff0c;但不要在Application中做耗时操作&#xff0c;然而有些初始化工作可能是很耗时的&#xff0c;那怎么办&#xff1f;初始化操作可以开启子线程来完成。 计算执行时间 常规…...

基于Python的微博大数据舆情分析,舆论情感分析可视化系统,可作为Python毕业设计

运行效果图 基于Python的微博大数据舆情分析&#xff0c;舆论情感分析可视化系统 系统介绍 微博舆情分析系统&#xff0c;项目后端分爬虫模块、数据分析模块、数据存储模块、业务逻辑模块组成。 先后进行了数据获取和筛选存储&#xff0c;对存储后的数据库数据进行提取分析处…...

被迫学习一波Linux命令

事情起因 部署一个服务&#xff0c;人家说了最低配置是3G&#xff0c;我没当回事&#xff0c;拿着个2G的服务器直接就上了&#xff0c;结果&#xff0c;哈哈&#xff0c;都能猜到结果&#xff1a;服务器内存爆了&#xff01;&#xff01;&#xff01;而且最可气的是服务器还登…...

字符串变量拼接操作的底层原理

在java中&#xff0c;字符串变量拼接操作使用的是StringBuilder或StringBuffer类&#xff0c;这两个类都是可变的字符串缓冲区。java中的字符串是不可变的&#xff0c;因此在进行字符串拼接时需要使用可变的字符串缓冲区&#xff0c;以避免不必要的内存分配和复制。具体来说&am…...

Wlan安全——认证与加密方式(WPA/WPA2)

目录 终端认证技术 WEP认证 PSK认证 802.1x认证与MAC认证 Portal认证 数据加密技术 WEP加密 TKIP加密 CCMP加密 TKIP和CCMP生成密钥所需要的密钥信息 802.11安全标准 WEP共享密钥认证、加密工作原理 WEP共享密钥认证 WEP加解密过程 PSK认证以及生成动态密钥的工…...

Leetcode-每日一题【剑指 Offer 31. 栈的压入、弹出序列】

题目 输入两个整数序列&#xff0c;第一个序列表示栈的压入顺序&#xff0c;请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如&#xff0c;序列 {1,2,3,4,5} 是某栈的压栈序列&#xff0c;序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列&#xf…...

软件需求-架构师之路(五)

软件需求 软件需求&#xff1a; 指用户 对系统在功能、行为、性能、设计约束等方面的期望。 分为 需求开发 和 需求管理 两大过程。 需求开发&#xff1a; 需求获取需求分析需求定义&#xff08;需求规格说明书&#xff09;需求验证&#xff1a;拉客户一起评审&#xff0c…...

Python自带的IDLE有什么用

在Python的官方解释器中&#xff0c;自带了一个名为IDLE(Interactive DeveLopment Environment)的集成开发环境。 一、简化代码调试过程 很多初学者在编写Python代码时&#xff0c;经常会遇到一些问题需要调试。而在IDLE中&#xff0c;我们可以通过设置断点、单步调试等方法&…...

设计模式之简单工厂模式

一、概述 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂模式使一个类的实例化延迟到其子类。 简单工厂模式&#xff1a;又叫做静态工厂方法模式&#xff0c;是由一个工厂对象决定创建出哪一种产品类的实例。 二、适用性 1.当一个类不知道它所必须…...

从SaaS到RPA,没有真正“完美”的解决方案!

众所周知&#xff0c;SaaS行业越来越卷&#xff0c;利润也越来越“薄”&#xff0c;这是传统软件厂商的悲哀&#xff0c;也是未来数字化行业不得不面对的冷峻现状之一。 随着基于aPaaS、低代码的解决方案之流行&#xff0c;SaaS行业变得越来越没有技术门槛&#xff0c;IT人员的…...

miniconda克隆arcpy

arcpy环境克隆 前言尝试思考到此结束 前言 最近遇到了一些问题&#xff0c;需要用到arcpy来处理一些东西&#xff0c;但众所周知&#xff0c;arcgis的arcpy是python 2.0的&#xff0c;我不是很喜欢&#xff1b;所以我安装了arcgis pro 2.8&#xff0c;我发现这也是个坑&#x…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...