网络编程之粘包解决方案
#解决方案1一收一发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #server.py import socket server = socket.socket() server.bind(( '192.168.15.57' , 8001 )) server.listen( 3 ) while 1 : print ( '等待连接。。。' ) conn,addr = server.accept() res1 = conn.recv( 1024 ).decode( 'utf-8' ) print ( 'res1:' ,res1) res2 = conn.recv( 1024 ).decode( 'utf-8' ) print ( 'res2:' ,res2) #client.py import socket client = socket.socket() client.connect(( '192.168.15.57' , 8001 )) client.send( '你好呀!!!' .encode( 'utf-8' )) client.send( '我叫赛丽亚^-^' .encode( 'utf-8' )) while 1 : pass client.close() |
#解决方案2,先发送长度,在发送数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #server.py import socket,subprocess,json server = socket.socket() server.bind(( '192.168.15.57' , 8001 )) server.listen( 3 ) while 1 : print ( '等待连接。。。' ) conn,addr = server.accept() print ( '连接成功!!!' ) while 1 : print ( '等待接受指令。。。' ) from_client_cmd = conn.recv( 1024 ).decode( 'utf-8' ) print ( '收到的命令:' ,from_client_cmd) if from_client_cmd.upper() = = 'Q' : break sub_obj = subprocess.Popen(from_client_cmd, shell = True , stdout = subprocess.PIPE, stderr = subprocess.PIPE) out = sub_obj.stdout.read() err = sub_obj.stderr.read() if out: conn.send(json.dumps( len (out)).encode( 'gbk' )) from_client_res = conn.recv( 1024 ).decode( 'utf-8' ) if from_client_res : conn.send(out) elif err: conn.send(json.dumps( len (err)).encode( 'gbk' )) from_client_res = conn.recv( 1024 ).decode( 'utf-8' ) if from_client_res: conn.send(err) print ( '断开连接。。。' ) conn.close() #client.py import socket,json client = socket.socket() client.connect(( '192.168.15.57' , 8001 )) while 1 : cmd = input ( '请输入命令:' ).replace( ' ' ,'') client.send(cmd.encode( 'utf-8' )) if cmd.upper() = = 'Q' : break from_server_msglen = json.loads(client.recv( 1024 ).decode( 'gbk' )) print ( '服务端要发送的数据长度:' ,from_server_msglen) client.send(json.dumps( 1 ).encode( 'utf-8' )) from_server_msg = client.recv(from_server_msglen) print ( '接收到的数据长度:' , len (from_server_msg)) print ( '收到的数据:' ) print (from_server_msg.decode( 'gbk' )) print ( '断开连接。。。' ) client.close() |
#解决方案3,自定义4字节报头,发送数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | #server.py import socket import struct import json import os tcp_server = socket.socket() ip_port = ( '127.0.0.1' , 8001 ) #127.0.0.1本机的回环地址,供内部程序之间测试用的 tcp_server.bind(ip_port) tcp_server.listen() #客户端上传的文件路径,都放在这个路径下 client_file_path = r 'D:\jj' conn,addr = tcp_server.accept() #首先接收到文件信息长度转换出来的4个字节的数据 file_info_stru = conn.recv( 4 ) #解包文件信息的长度 file_info_len = struct.unpack( 'i' ,file_info_stru)[ 0 ] #然后接收文件的描述信息 client_file_info = conn.recv(file_info_len).decode( 'utf-8' ) #将接收到的json字符串反序列化 abc_file_info = json.loads(client_file_info) print ( 'abc_file_info>>>' ,abc_file_info) client_file_size = abc_file_info[ 'file_size' ] recv_all_size = 0 #拼接一下全路径 client_full_path = client_file_path + '\\' + abc_file_info[' file_name'] # client_full_path = os.path.join(client_file_path,abc_file_info['file_name']) with open (client_full_path, 'wb' ) as f: while recv_all_size < client_file_size: every_recv_data = conn.recv( 1024 ) f.write(every_recv_data) recv_all_size + = len (every_recv_data) conn.send( '小伙玩的行,上传成功!' .encode( 'utf-8' )) conn.close() tcp_server.close() #client.py import socket import struct import os import json tcp_client = socket.socket() server_ip_port = ( '127.0.0.1' , 8001 ) tcp_client.connect(server_ip_port) read_size = 1024 file_info = { 'file_path' :r 'D:\python_workspace\day030\aaa.mp4' , 'file_name' : 'aaa.mp4' , 'file_size' : None , } #获取文件大小 file_size = os.path.getsize(file_info[ 'file_path' ]) #将文件大小添加到文件信息的字典中 file_info[ 'file_size' ] = file_size #因为我们要发送的数据是字节类型,那么必须将字典转换为bytes类型,但是字典不能直接转换为bytes,所以我们想到了json, #通过json模块将字典类型的文件信息数据转换为了json类型的字符串 file_info_json = json.dumps(file_info) #获取了字符串的长度 file_info_len = len (file_info_json) #将长度打包为4个字节的数据, file_info_stru = struct.pack( 'i' ,file_info_len) #将打包好的4个自己的数据和我的文件信息数据一起发送给了服务端 tcp_client.send(file_info_stru) tcp_client.send(file_info_json.encode( 'utf-8' )) #统计文件数据 all_file_data = b'' #统计文件数据长度 all_size_len = 0 with open (file_info[ 'file_path' ], 'rb' ) as f: while all_size_len < file_size: every_read_data = f.read(read_size) all_file_data + = every_read_data all_size_len + = len (every_read_data) #发送每次读取的数据 tcp_client.send(every_read_data) print (tcp_client.recv( 1024 ).decode( 'utf-8' )) tcp_client.close() |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· dotnet 源代码生成器分析器入门
· 官方的 MCP C# SDK:csharp-sdk
· 一款 .NET 开源、功能强大的远程连接管理工具,支持 RDP、VNC、SSH 等多种主流协议!
· 一步一步教你部署ktransformers,大内存单显卡用上Deepseek-R1
· 一次Java后端服务间歇性响应慢的问题排查记录