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 ...
随机推荐
- AngularJS 指令(意义)
angular.module('modulename') .directive('myDirective', function(){ return { restrict: 'EA', //E表示ele ...
- python使用ddt模块对用例执行操作
import time import unittest import ddt from selenium import webdriver TEST_URL = "http://www.ba ...
- Nginx(二) 反向代理&负载均衡
1.反向代理 当我们请求一个网站时,nginx会决定由哪台服务器提供服务,就是反向代理. nginx只做请求的转发,后台有多个tomcat服务器提供服务,nginx的功能就是把请求转发给后面的服务器, ...
- 基于.Net Core的API框架的搭建(4)
6.加入日志功能 日志我们选用log4net,首先引入程序包: 选择2.0.8版本安装.然后在项目根目录新增log4net的配置文件log4net.config: <?xml version=& ...
- 树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland
题目传送门 /* 题意:求一个点为根节点,使得到其他所有点的距离最短,是有向边,反向的距离+1 树形DP:首先假设1为根节点,自下而上计算dp[1](根节点到其他点的距离),然后再从1开始,自上而下计 ...
- 312 Burst Balloons 戳气球
现有 n 个气球按顺序排成一排,每个气球上标有一个数字,这些数字用数组 nums 表示.现在要求你戳破所有的气球.每当你戳破一个气球 i 时,你可以获得 nums[left] * nums[i] * ...
- C# 调用非托管函数
C#通过DllImport可以直接调用Windows中的一些功能.C++中已经编写好的一些方法: DllImport所在的名字空间:System.Runtime.InteropServices; Dl ...
- 致创业者:APP已死 服务永生
前几日,有位创业者和我讲他在带领团队做一个将爱踢球的人集中在一起的App,我告诉他你的创业方向错了.原因在于你的目的是要为爱踢球的人提供服务,而你现在却在竭尽全力的做App,你应该做的是设计你为爱踢球 ...
- Spring.Net学习笔记(0)-错误汇总
1.错误一:ObjectDefinitionStoreException "Spring.Objects.Factory.ObjectDefinitionStoreException&quo ...
- System.AppDomain类详解(二)
进程是存在独立的内存和资源的,但是AppDomain仅仅是逻辑上的一种抽象.一个process可以存在多个AppDomain.各个AppDomain之间的数据时相互独立的.一个线程可以穿梭多个AppD ...