python socket实现文件传输(防粘包)
1.文件传输的要点:
采用iterator(迭代器对象)迭代读取,提高读取以及存取效率;
通过for line in file_handles逐行conn.send();
2.socket粘包问题:
[出现原因]:A.TCP协议为了提高传输效率,发送方往往需要收集定量的数据才会封装给底层并发送,若出现连续send(data),TCP会把该数据进行整合(直到装满数据缓冲区),这样就造成了粘包数据;B.接收方接收方的粘包是由于接收用户相关进程不及时接收数据,从而导致粘包问题,这是因为接收方先把接收到的数据放在系统接受缓冲区,用户进程从该缓冲区取定量的数据,但若下一包数据到达前,缓冲区的数据没有及时的被用户进程取走,则下一包数据与前一包部分数据在系统缓冲区,就可能导致用户设定的进程缓冲区从系统缓冲区取走两个包的部分数据,从而导致粘包
[解决办法]:A 发送方在send()之前,先向接收方发送数据总量大小,并通过双端确认,server端发送数据包,然后接收方通过按数据量大小循环设立缓冲区接收数据;;B: TCP提供了PUSH(强制数据立即传送)操作,但影响性能;C. 周全并且高效的处理粘包请参考:点击这里
3.code
server.py
__author__ = 'kisunny'
import socket,os,hashlib
server = socket.socket()
server.bind(('localhost',6669))
server.listen(2)
count = 0
while 1:
conn,addr = server.accept()
count+=1
print('客户端%s已连接上!' % count)
while 1:
cmd = conn.recv(1024)
order,filename1 = str(cmd.decode()).split()
if os.path.isfile(filename1):
print('命令:%s\n待发送的文件名:%s' % (order,filename1))
#发送文件的大小及文件名
post_server = filename1+' '+str(os.stat(filename1).st_size)
conn.send(post_server.encode(encoding='utf-8'))
#发送文件确认号
ACK = conn.recv(1024)
#16进制摘要
m = hashlib.md5()
with open(filename1,'rb') as f:
for line in f:
m.update(line)
conn.send(line)
print('%s发送完毕!' % filename1)
#此处循环完成之后,继续send(),可能出现socket粘包
conn.send(m.hexdigest().encode())
continue
else:
ERROR = '错误!请检查文件名!'
conn.send(ERROR.encode(encoding='utf-8'))
server.close()
client.py
__author__ = 'kisunny'
import socket,hashlib
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('localhost',6669))
print('连接服务器成功!')
while 1:
print('请输入请求信号及请求内容\n格式:response filename')
cmd_order = input('>>:').strip()
client.send(cmd_order.encode('utf-8'))
cls_msg = client.recv(1024)
try:
filename2,file_size = str(cls_msg.decode()).split()
except ValueError as e:
print(e)
continue
else:
file_len = int(file_size)
print('待传输文件大小:%s' % file_len)
temp = 0
client.send('已发送!'.encode(encoding='utf-8'))
#MD5对象
m_client = hashlib.md5()
while temp<file_len:
with open('another.txt','wb') as f:
#避免服务器连续send出现粘包
if temp+1024>file_len:
last_len = file_len - temp
data_temp = client.recv(last_len)
else:
data_temp = client.recv(1024)
f.write(data_temp)
m_client.update(data_temp)
temp += len(data_temp)
print('接收文件完毕!\n实际接收文件大小:%s' % temp)
#接收16进制摘要
md5_info = client.recv(1024)
if md5_info.decode() == m_client.hexdigest():
print('MD5验证成功!')
client.close()
功能未完善,仅做DEMO参考
哈哈,好好学习,加油!
python socket实现文件传输(防粘包)的更多相关文章
- python socket 连续send,出现粘包问题
使用网上socket代码实现ssh功能,如下: server.py #服务端Linux系统下:处理命令并返回import socketimport os#声明类型,生成socket链接对象server ...
- 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天
由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...
- python套接字解决tcp粘包问题
python套接字解决tcp粘包问题 目录 什么是粘包 演示粘包现象 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数 ...
- 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法
网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...
- Python之路 - 网络编程之粘包
Python之路 - 网络编程之粘包 粘包
- python开发socket套接字:粘包问题&udp套接字&socketserver
一,发生粘包 服务器端 from socket import * phone=socket(AF_INET,SOCK_STREAM) #套接字 phone.setsockopt(SOL_SOCKET, ...
- python基础--socket套接字、粘包问题
本地回环地址:127.0.0.1 简易版服务端: import socket server = socket.socket() # 就比如买了一个手机 server.bind(("127 ...
- 初始socket模块和巧解粘包问题
1.什么是socket? 两个进程如果需要进行通讯最基本的一个前提能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大 ...
- Python网络编程(2)-粘包现象及socketserver模块实现TCP并发
1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...
随机推荐
- 【158】◀▶ Linux-Bash学习
鸟哥的 Linux 私房菜 Linux 的 26 个命令 Shell 脚本教程 Linux 命令大全 目录——按文件顺序: echo:显示变量内容 printf:格式化输 ...
- bzoj 1026: [SCOI2009]windy数【数位dp】
忘记limit不能记WA了一发-- 典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于 ...
- Unity项目 - Boids集群模拟算法
1987年Craig W.Reynolds发表一篇名为<鸟群.牧群.鱼群:分布式行为模式>的论文,描述了一种非常简单的.以面向对象思维模拟群体类行为的方法,称之为 Boids ,Boids ...
- thinkphp 5 常用的助手函数
load_trait:快速导入Traits,PHP5.5以上无需调用 /** * 快速导入Traits PHP5.5以上无需调用 * @param string $class t ...
- NET 编程题
1.C#编写创建一个线程的代码 using System; using System.IO; using System.Threading ; class MyThread{ public int c ...
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 The Heaviest Non-decreasing Subsequence Problem
Let SS be a sequence of integers s_{1}s1, s_{2}s2, ......, s_{n}snEach integer is is associ ...
- ORA-01654_TableSpace空间不足问题处理
操作环境:Windows Server 2008 R2,32位Oracle11g R2. 导入大批量数据时报如下错误信息: ORA-: 索引IOT.IDX_IOT_EQUIP_ID无法通过1024(在 ...
- php 5.6 版本配置 oracle ddl
1. Windows版PHP内置了Oracle驱动,在ext目录下:php_oci8.dllphp_oci8_11g.dllphp_pdo_oci.dllLinux上如果自己编译的话则添加下面的con ...
- 385 Mini Parser 迷你解析器
Given a nested list of integers represented as a string, implement a parser to deserialize it.Each e ...
- 274 H-Index H指数
给定一位研究者的论文被引用次数的数组(被引用次数是非负整数).写一个方法计算出研究者的H指数.H-index定义: “一位科学家有指数 h 是指他(她)的 N 篇论文中至多有 h 篇论文,分别被引用了 ...