pyftpdlib 搭建FTP服务器
学会socket之后,就可以使用应用层的协议了,比如FTP,HTTP等,不过一般这些应用层都会有现成的模块,学不学socket都无所谓,这是python的方便之处。这里搭建FTP服务器使用的就是pyftpdlib。这个模块使用起来非常简单。
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import os
def main():
# Instantiate a dummy authorizer for managing 'virtual' users
authorizer = DummyAuthorizer()
# Define a new user having full r/w permissions and a read-only
# anonymous user
authorizer.add_user('user', '12345', '.', perm='elradfmwM')
authorizer.add_anonymous("F:/")
# Instantiate FTP handler class
handler = FTPHandler
handler.authorizer = authorizer
# Define a customized banner (string returned when client connects)
handler.banner = "pyftpdlib based ftpd ready."
# Specify a masquerade address and the range of ports to use for
# passive connections. Decomment in case you're behind a NAT.
#handler.masquerade_address = '151.25.42.11'
#handler.passive_ports = range(60000, 65535)
# Instantiate FTP server class and listen on 0.0.0.0:2121
address = ('127.0.0.1', 2121)
server = FTPServer(address, handler)
# set a limit for connections
server.max_cons = 256
server.max_cons_per_ip = 5
# start ftp server
server.serve_forever()
if __name__ == '__main__':
main()
使用上述代码即可搭建一个匿名的ftp服务器,在浏览器窗口输入 ftp:\\localhost:2121
即可看到文件目录。
支持的功能
- 基本的匿名ftp服务器
- log功能
- 用户加密(可以使用电脑的用户名和密码)
- TLS/SSL传输加密
- 并发连接
- 带宽限制
上述这些功能的详细介绍可以在turorail找到
命令行使用
简单的FTP服务器在安装这个模块后,可以使用命令行开启:
python -m pyftpdlib -i 192.168.20.195 -p 8021 -d E: -w
上面命令的意思是开启一个FTP服务器,目录为E盘,并且可以写入文件(-w)。为了更方便的上传下载文件,推荐使用FileZilla,而不是浏览器。
更多内容
为了方便操作,重写了一个脚本,自动打开服务,并复制地址到粘贴板
import subprocess
import re
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import sys
import os
import ctypes
import pyperclip
def getIp():
args = [r"powershell", r"(ipconfig | findstr IPv4)"]
ip = subprocess.run(args, stdout=subprocess.PIPE)
ipString = ip.stdout.decode("gb2312")
reip = re.compile(r'(?<![\.\d])(?:\d{1,3}\.){3}\d{1,3}(?![\.\d])')
counter = 0
ipList = []
for ip0 in reip.findall(ipString):
ipList.append(ip0)
print("ip%d : %s" % (counter, ip0))
counter += 1
return ipList[0]
def setFtpServer(ip, path):
authorizer = DummyAuthorizer()
authorizer.add_user('user', '12345', '.', perm='elradfmwM')
authorizer.add_anonymous(path)
handler = FTPHandler
handler.authorizer = authorizer
handler.banner = "pyftpdlib based ftpd ready."
address = (ip, 21)
server = FTPServer(address, handler)
server.max_cons = 256
server.max_cons_per_ip = 5
server.serve_forever()
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
# 字体颜色定义 ,关键在于颜色编码,由2位十六进制组成,分别取0~f,前一位指的是背景色,后一位指的是字体色
# 由于该函数的限制,应该是只有这16种,可以前景色与背景色组合。也可以几种颜色通过或运算组合,组合后还是在这16种颜色中
# Windows CMD命令行 字体颜色定义 text colors
FOREGROUND_BLACK = 0x00 # black.
FOREGROUND_DARKBLUE = 0x01 # dark blue.
FOREGROUND_DARKGREEN = 0x02 # dark green.
FOREGROUND_DARKSKYBLUE = 0x03 # dark skyblue.
FOREGROUND_DARKRED = 0x04 # dark red.
FOREGROUND_DARKPINK = 0x05 # dark pink.
FOREGROUND_DARKYELLOW = 0x06 # dark yellow.
FOREGROUND_DARKWHITE = 0x07 # dark white.
FOREGROUND_DARKGRAY = 0x08 # dark gray.
FOREGROUND_BLUE = 0x09 # blue.
FOREGROUND_GREEN = 0x0a # green.
FOREGROUND_SKYBLUE = 0x0b # skyblue.
FOREGROUND_RED = 0x0c # red.
FOREGROUND_PINK = 0x0d # pink.
FOREGROUND_YELLOW = 0x0e # yellow.
FOREGROUND_WHITE = 0x0f # white.
# Windows CMD命令行 背景颜色定义 background colors
BACKGROUND_BLUE = 0x10 # dark blue.
BACKGROUND_GREEN = 0x20 # dark green.
BACKGROUND_DARKSKYBLUE = 0x30 # dark skyblue.
BACKGROUND_DARKRED = 0x40 # dark red.
BACKGROUND_DARKPINK = 0x50 # dark pink.
BACKGROUND_DARKYELLOW = 0x60 # dark yellow.
BACKGROUND_DARKWHITE = 0x70 # dark white.
BACKGROUND_DARKGRAY = 0x80 # dark gray.
BACKGROUND_BLUE = 0x90 # blue.
BACKGROUND_GREEN = 0xa0 # green.
BACKGROUND_SKYBLUE = 0xb0 # skyblue.
BACKGROUND_RED = 0xc0 # red.
BACKGROUND_PINK = 0xd0 # pink.
BACKGROUND_YELLOW = 0xe0 # yellow.
BACKGROUND_WHITE = 0xf0 # white.
# get handle
std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
def set_cmd_text_color(color, handle=std_out_handle):
Bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
return Bool
# reset white
def resetColor():
set_cmd_text_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
# 绿色
# green
def printGreen(mess):
set_cmd_text_color(FOREGROUND_GREEN)
sys.stdout.write(mess)
resetColor()
if __name__ == "__main__":
path = os.getcwd()
if len(sys.argv) == 2:
path = sys.argv[1]
ip = getIp()
set_cmd_text_color(FOREGROUND_GREEN)
print("you have shared %s" % path)
print(r"you can visit ftp://%s now" % ip)
print("address has copy to you clipboard")
resetColor()
pyperclip.copy("ftp://" + ip)
setFtpServer(ip, path)