一.socket网络编程
粘包:服务端两次发送指令在一起,它会把两次发送内容合在一起发送,称为粘包,从而出现错误。
解决方法:(比较low的方法)
有些需要实时更新的,用sleep有延迟,不能这样解决问题。
解决方法之高级方法:
客户端:
二.发送文件
ftp server端有哪几步呢?
①读取客户端发过来的文件名
②检测文件是否存在
③打开文件
④检测文件大小
⑤发送文件大小给客户端
⑥等待客户端确认
⑦开始边读边发数据
⑧发送md5
1 import socket 2 import os 3 import time 4 import hashlib 5 server = socket.socket() 6 server.bind(('localhost',3333)) 7 8 server.listen() 9 10 while True: 11 conn,addr = server.accept() 12 print("new conn:",addr) 13 while True: 14 print("等待新指令") 15 data = conn.recv(1024) 16 if not data: 17 print("客户端已断开") 18 break 19 cmd,filename = data.decode().split() 20 print(filename) 21 if os.path.isfile(filename): 22 f = open(filename,"rb") 23 m = hashlib.md5() 24 file_size = os.stat(filename).st_size #在os模块中获取文件大小 25 conn.send(str(file_size).encode()) #发送文件大小 26 conn.recv(1024) #wait for ack 27 for line in f: 28 m.update(line) 29 conn.send(line) 30 print("file md5",m.hexdigest()) 31 f.close() 32 conn.send(m.hexdigest().encode()) #send md5 33 34 print("执行指令:", data) 35 36 server.close()
客户端:
1 import socket 2 import hashlib 3 client = socket.socket() 4 client.connect(('localhost',3333)) 5 6 while True: 7 cmd = input(">>:").strip() #cmd = input(b">>:").strip()如果前面直接加b,则只能传英文 8 if len(cmd) == 0 : continue 9 if cmd.startswith("get"): 10 client.send(cmd.encode()) 11 server_response = client.recv(1024) 12 print("server response:",server_response) 13 client.send("ready to recv file".encode()) 14 file_total_size = int(server_response.decode()) 15 received_size = 0 16 filename = cmd.split()[1] 17 f = open("wenjian","wb") 18 m = hashlib.md5() 19 20 while received_size<file_total_size: 21 #下面这段代码彻底解决粘包问题 22 if file_total_size - received_size > 1024: #要收不止一次 23 size = 1024 24 else: 25 size = file_total_size - received_size #最后一次了,剩多少收多少 26 print("last receive:",size) 27 28 data = client.recv(1024) 29 received_size += len(data) 30 m.update(data) 31 f.write(data) 32 print(file_total_size,received_size) #看演示效果 33 else: 34 new_file_md5 = m.hexdigest() 35 print("file received done",received_size,file_total_size) 36 f.close() 37 server_file_md5 = client.recv(1024) 38 print("server file md5:",server_file_md5) 39 print("client file md5:", new_file_md5) 40 41 42 client.close()
具体用的时候在钻研吧。