python------Socket网络编程(二)粘包问题
一.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()
具体用的时候在钻研吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了