socket用户交互+MD5加密
利用socket从client传输文件指令于server 再返还字节大小与内容
socketserver的使用(重要)
注意:
##client.recv(1024)此句指令尤为重要
--每次收到最大1024 一般都小于1024,
-因此必须判断每次传输的字节大小 并累加 直到保证接收到的内容不小于server发出的内容
-否则一直继续传输
client代码
import socket client=socket.socket() client.connect(('localhost',999)) while True: cmd=input(">>:").strip() if len(cmd)==0: continue client.send(cmd.encode("utf-8")) cmd_res_size=client.recv(1024) #接收命令长度 print("命令长度为",cmd_res_size.decode()) receive_size=0 while receive_size!=int(cmd_res_size.decode()): cmd_res=client.recv(1024) #每次收到最大1024 一般都小于1024,不能用for判断 receive_size+=len(cmd_res.decode()) print(cmd_res.decode()) print("done 打印长度为",receive_size) client.close()
server代码
import socket,os server=socket.socket() server.bind(('localhost',999)) server.listen() while True: conn,addr=server.accept() print("new conn",addr) while True: data=conn.recv(1024) if not data: print("用户已断开") break print("执行指令:",data) cmd_res=os.popen(data.decode()).read() if len(cmd_res) == 0: cmd_res = "your input is wrong!" conn.send(str(len(cmd_res)).encode("utf-8")) conn.send(cmd_res.encode("utf-8")) server.close()
补充:
1.只有String 型才有encode转码,因此其他int/double型需先转成String型
2.send函数只能传输byte型字节,对于ASCII码的字符串 可在前面直接加b进行转码操作 例:b‘ssadads’
但若要将中文字符转ASCII码 必须使用encode转码 (此在day4学python中有详细讲解)
3.字节型用len测量和字符串型不同 即使两边数字都相同 len后的值依旧不同
要比较值时,先字符串型decode解码或字节型转码 方可进行比较
*****************************************************************************************************************************************************************
socket升级版 socketserver重点关注
import socketserver #对socket进行封装 class MyTCP(socketserver.BaseRequestHandler): #定义处理类,继承于BaseRequestHandler def handle(self): #与所有客户端的交互都在handle里完成 重写此函数 while True: try: self.data=self.request.recv(1024).strip() #接收信息 print(self.client_address[0],"write") #显示用户ip print(self.data) #打印传输数据 if not self.data: self.request.send(self.data.upper()) #返回大写 except ConnectionRefusedError as e: #抓住异常并打印 print("err",e) break HOST,PORT="localhost",999 #初始化 #server=socketserver.TCPServer((HOST,PORT),MyTCP) #单线程 实例化一个server对象 server=socketserver.ThreadingTCPServer((HOST,PORT),MyTCP) #多线程 实例化一个server对象 server.serve_forever() #处理请求 永远执行 server.close()
作为服务端,可支持多线程 多方面client的请求
=======================================
补充:
传输文件以MD5形式加密
import socket,hashlib client=socket.socket() #实例化socket对象 client.connect(("localhost",999)) #连接 while True: cmd=input(">>:".strip()) #用户输入指令 去空格 if len(cmd)==0:continue #输入为空重新输入 if cmd.startswith("get"): #指令以get开头 client.send(cmd.encode()) #发送命令 server_response=client.recv(1024) #接收server端回复 print("文件大小",server_response.decode()) #打印server端的信息(文件大小) client.send(b"ready......") #回复server端 size=int(server_response.decode()) #文件大小 receive_size=0 #接收信息size累加 filename=cmd.split()[1] #文件名 f=open("lala","wb") #打开文件 m=hashlib.md5() #实例化MD5加密 while receive_size<size: #由于client传输的信息每次传输最大为1024 但实际不到 if(size-receive_size>1024): #因此每次都得累加传输的信息数量与总理做对比 a=1024 else: a=size-receive_size print(a,size,receive_size) data=client.recv(a) #接收client传输的信息 receive_size+=len(data) #累加 m.update(data) #MD5累加数据用update函数 f.write(data) print("file rece done") new_file_md5=m.hexdigest() #16进制数据字符串 f.close() server_file_md5=client.recv(1024) print("server file",server_file_md5) print("client file",new_file_md5) client.close()
可直接对接 上方socketserver