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 ...
随机推荐
- not syncing : corrupted stack end detected inside scheduler
自己在测试安装UBuntu的时候遇见了这个错误,not syncing : corrupted stack end detected inside scheduler解决办法 原因是低版本的VMwar ...
- makefile 参数
GNU Make make是负责从项目的源代码中生成最终可执行文件和其他非源代码文件的工具. make命令本身可带有四种参数:标志.宏定义.描述文件名和目标文件名. 其标准形式为:make [flag ...
- 27. FormPanel类的defaults属性
defaults : Object defaults属性可以包含任意个name/value属性对,这些属性将会被添加到每一个元素中...例如, 为了自动向容器包含的每个Ext.Panel 元素的宽度添 ...
- NestedPreb
屌丝手动版 One of the things we’re sorely missing from Unity is nested prefabs. So we rolled this little ...
- robotframework - Edit编辑器
1.测试项目&套件 提供的Edit编辑器 2.在 Edit 标签页中主要分:加载外部文件.定义内部变量.定义元数据等三个部分. (1):加载外部文件Add Library:加载测试库,主要是[ ...
- codechef : TREDEG , Trees and Degrees
其实有原题,生成树计数 然鹅这题里面是两道题, 50pts 可以用上面那题的做法直接过掉,另外 50pts 要推推式子,搞出 O n 的做法才行(毕竟多项式常数之大您是知道的) 虽说这道题里面是没有 ...
- python自动化学习笔记10-数据驱动DDT与yml的应用
在测试工作中,针对某一API接口,或者某一个用户界面的输入框,需要设计大量相关的用例,每一个用例包含实际输入的各种可能的数据.通常的做法是,将测试数据存放到一个数据文件里,然后从数据文件读取,在脚本中 ...
- jquery实现点击进入新的页面。(jquery实现超链接)
<script src="jquery-1.9.1.min.js" type="text/javascript"></script> & ...
- 继续C#开发or转做产品
本人今年大四,C#开发,在一家公司实习了一年后,面临一个选择,是继续C#开发还是转做产品?我C#开发能力目前还一般,但很有兴趣.也喜欢设计与创意,做过产品专员.求大婶们指导!
- PHP实现写LOG日志的代码
这篇文章给大家介绍的内容是关于PHP实现写LOG日志的代码,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. public function write_log(){ //设置目录时间 ...