#动态导入 官方建议
import importlib
import_str="lib.aa"
lib=importlib.import_module(import_str)
obj=lib.A("dfasfdasfasfsdfsadfasf")
print(obj)
# #动态导入 另一种形式
# import_str = "lib.aa"
# mod= __import__("lib.aa")
# a=mod.aa.A("adasfaf")
# print(a)
断言:
assert type(obj.name) is str
复习Socket:
server=socket.socket(AF>INET,sock.SOCK_STREAM)
server.bind(localhost,9999)
server.listen()
conn,addr = server.accept()
while True:
print("new conn",addr)
data = conn.recv(102400)
print(data.upper())
编写一个ssh实例:详见20180807
socket的粘包:即如果socket连续执行两次以上send()可能会合并成一次缓冲发送,接收到的数据会将两个包的内容黏在一起
解决办法:在每两次发送之间,做一次数据接收处理。
Ftp server:
1 读取文件名
2检测文件是否存在
3 打开文件
4 检测文件大小
5 发送文件大小
6 等客户端确认
7 边读边发
8 md5发送及确认
实例实现源码:
socket_ftp_server:
# Author:huhu
import socket,os,time,hashlib
server=socket.socket()
server.bind(("localhost",6970))
server.listen()
while True:
print("开始监听...")
conn,addr = server.accept()
print("建立新连接",addr)
data =conn.recv(1024)
print("ask file name is %s"%data.decode())
if not data:
print("客户端已断开")
break
cmd,filename = data.decode().split()
print(filename)
if os.path.isfile(filename):
f=open(filename,"rb")
m=hashlib.md5()
file_size=os.stat(filename).st_size
conn.send(str(file_size).encode())
conn.recv(1024)
for line in f:
m.update(line)
conn.send(line)
print("md5",m.hexdigest())
f.close()
print("send done")
server_confirm=conn.recv(1024)#等待客户端确认接收完成
conn.send(m.hexdigest().encode())
server.close()
socket_ftp_client:
# Author:huhu
import socket,hashlib
client=socket.socket()
client.connect(("localhost",6970))
while True:
cmd = input(">>:".strip())
if len(cmd) == 0:
continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("server response:",server_response)
client.send(b"ready to recv file")
file_total_size = int(server_response.decode())
received_size=0
filename = cmd.split()[1]
f = open(filename+".new","wb")
m=hashlib.md5()
while received_size<file_total_size:
if file_total_size-received_size >= 1024:
size=1024
else:
size = file_total_size-received_size
print("last receive size:",size)
data = client.recv(size)
m.update(data)
received_size +=len(data)
f.write(data)
print("receiving %s %%"%round(received_size/file_total_size*100,2))
else:
print("receiving 100 % done")
print(file_total_size, received_size)
f.close()
new_file_md5=m.hexdigest()
#接收完成后向服务器端确认数据收完
client.send(b"all data been received")
print(new_file_md5)
server_file_md5=client.recv(1024).decode()
print("server file md5:",server_file_md5)
print("client rev file md5:",new_file_md5)
SocketServer:最主要的作用:用来支持多并发
定义:用于将网络服务器的编程更容易更简化
类型:TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer
创建一个SocketServer的过程:
1 自己创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还要重写handle()方法
2 你必须实例化TCPServer,并且传递server ip 和你上面创建的请求处理类给这个TCPServer
3 server.serve_forever()来处理多个请求,永远执行
server.handle_request()只能处理一个请求
SocketServer:
# Author:huhu
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
'''
自定义Socketserver类的请求类
'''
def handle(self):
print("{} connected:".format(self.client_address))
while True:
try:
self.data=self.request.recv(1024).strip()
print("{}:{} wrote:".format(self.client_address[0],self.client_address[1]))
print(self.data)
self.request.send(self.data.upper())
except ConnectionResetError as e:
print("err:",e)
break
if __name__=="__main__":
HOST,PORT="localhost",9999
# server=socketserver.TCPServer((HOST,PORT),MyTCPHandler)
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
本节作业:开发一个多用户使用的FTP系统
作业要求:
1 用户加密认证
2允许同事多用户登录
3 每个用户有自己的家目录,且只能访问自己的家目录
4 对用户进行磁盘配额,每个用户的可用空间不同
5 允许用户在ftp server上随意切换目录
6 允许用户查看当前目录下文件
7 允许上传和下载文件,保证文件一致性
8 文件传输过程中显示进度条
9 附加功能 :支持文件的断点续传
初步老师带着做了一部分(180808下),剩下的自己研究去一点点的实现吧~~~