使用socketserver进行多用户的文件传输

服务端

class FtpServer(socketserver.BaseRequestHandler):  # 继承socketserver.BaseRequestHandler
  def handle(self):   #handle必须有,是派生方法是重定义继承的handle,是用于处理交互
    pass

客服端

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
# 建立连接

开启服务

server = socketserver.ThreadingTCPServer((HOST, PORT), FtpServer)  # 创建socketserver对象
server.serve_forever() # 开启服务(一直开启)

handle

def handle(self):
"""处理与用户的命令"""
while self:
"""用于解决黏包问题"""
header_size = struct.unpack('i', self.request.recv(4))[0] # 接收自定义包头
header_bytes = self.request.recv(header_size)
header = json.loads(header_bytes.decode('utf-8'))
action_type = header.get('type')
""""用反射调用方法"""
if hasattr(self, '_' + action_type):
getattr(self, '_' + action_type)(header)
else:
print('invalid command')

服务端自定义的发送包头

def _send(self, status_code, **kwargs):
msg = kwargs
msg['status_code'] = status_code
msg['status_msg'] = self.STATUS_CODE[status_code]
bytes_data = json.dumps(msg).encode('utf-8')
self.request.send(struct.pack('i', len(bytes_data)))
self.request.send(bytes_data)

服务端转到客服端

def _get(self, header):
filename = header.get('filename')
if os.path.isfile(file_path):
file_size = os.stat(filename ).st_size
self._send(size=file_size) # 先发送包头
print("ready to send file ")
f = open(file_path, 'rb')
for line in f:
self.request.send(line)
else:
print('file send done..', filename )
f.close()
else:
self_send(size=0)

客户端接收

def get(filename):
_send(type='get', filename=filename) # 发送自定义头
header = _recv() # 接收自定义头
size = header.get('size')
if size:
f = open(filename, 'wb')
while size: # 接收数据
if size >= 1024:
data = sock.recv(1024)
f.write(data)
f.flush()
size -= len(data) # len(data)为接收到的数据长度,如果写1024的话可能会出现数据接收不完整的问题
else:
data = sock.recv(size)
f.write(data)
f.flush()
size -= len(data) # 同理
if size == 0:
break
f.close()

客服端包头的发送和接收

def _send(**kwargs):
"""发送"""
msg = kwargs
header_bytes = json.dumps(msg).encode('utf-8')
sock.send(struct.pack('i', len(header_bytes)))
sock.send(header_bytes) def _recv():
"""接收"""
header_size = struct.unpack('i', sock.recv(4))[0]
header_bytes = sock.recv(header_size)
header = json.loads(header_bytes.decode('utf-8'))
return header

python学习之利用socketserver的文件传输的更多相关文章

  1. python学习笔记(六)文件夹遍历,异常处理

    python学习笔记(六) 文件夹遍历 1.递归遍历 import os allfile = [] def dirList(path): filelist = os.listdir(path) for ...

  2. Python学习系列(五)(文件操作及其字典)

    Python学习系列(五)(文件操作及其字典) Python学习系列(四)(列表及其函数) 一.文件操作 1,读文件      在以'r'读模式打开文件以后可以调用read函数一次性将文件内容全部读出 ...

  3. 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天

    由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...

  4. Python实现多种SSH连接与文件传输

    Python实现SSH控制 使用Python进行基于口令认证的连接: 1 #加载paramiko包 2 import paramiko 3 #创建新的SSH对象 4 Client=paramiko.S ...

  5. 我们一起学习WCF 第六篇文件传输

    原文  http://www.cnblogs.com/LipeiNet/p/4653830.html   前言:文件的输出我们并不陌生,但是今天我写的是用wcf模式进行文件传输,我觉得一大好处就是能进 ...

  6. 吴裕雄--天生自然python学习笔记:Python3 File(文件) 方法

    open() 方法 Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError. 注意:使用 open() ...

  7. python学习笔记——(三)文件操作

    ·集合操作及其相应的操作符表示集合中没有插入,只有添加,因为毕竟无序 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Vergil Zhan ...

  8. 老男孩 python学习自修第二十二天【文件上传与下载】

    1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...

  9. python学习笔记(二)文件操作和集合

    集合: 集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据 集合的作用: 1.它可以把一个列表中重复的数据去掉,而不需要你再写判断 2.可以做关系测试, ...

随机推荐

  1. js使浏览器窗口最大化(适用于IE的方法)

    这里使用的方法是IE的私有特性,只能在IE中有效.主要是window.moveTo和 window.resizeTo方法.       效果和点击最大化按钮差不多,有一点区别.点击最大化按钮后,浏览器 ...

  2. getaddrinfo工作原理分析

    getaddrinfo工作原理分析 将域名解析成ip地址是所有涉及网络通讯功能程序的基本步骤之一,常用的两个接口是gethostbyname和getaddrinfo,而后者是Posix标准推荐在新应用 ...

  3. Metasploit使用内网跳板, 扫描局域网主机

    最近,拿到一台内网机器, 苦于无法使用nmap扫描改主机的内网, 所以才有此文 在跳板机子获取一定权限后,需要积极的向内网主机权限发展,获取指定的目标信息,探查系统漏洞,借助msf已经得到的meter ...

  4. Keras split train test set when using ImageDataGenerator

    Keras split train test set when using ImageDataGenerator I have a single directory which contains su ...

  5. 小米手机root

    目录 概念 解锁流程 root流程 如何Root? 关于supersu 关于twrp 关于Magisk Manager ref: 申请开发板流程 线刷教程 小米手机root 概念 解锁: 使手机可以刷 ...

  6. Scrapy的 Shell终端

    crapy Shell Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据. ...

  7. 更换yum源为阿里云源

    1.复制备份: cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2.下载: wget -O ...

  8. EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器和EasyDSS云平台异同

    背景分析 不同于EasyDSS流媒体服务器与EasyDSS流媒体解决方案(EasyDSS流媒体解决方案就是通过EasyDSS流媒体服务器完善业务层研发而来),EasyDSS流媒体服务器和EasyDSS ...

  9. JAVA中生成指定位数随机数的方法总结

    JAVA中生成指定位数随机数的方法很多,下面列举几种比较常用的方法. 方法一.通过Math类 public static String getRandom1(int len) { int rs = ( ...

  10. windows mysql手动添加my.ini 服务启动不了

    [mysqld] character-set-server=utf8 #绑定IPv4和3306端口 bind-address=0.0.0.0 port= default_storage_engine= ...