程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

python学习之利用socketserver的文件传输

发布于2019-11-07 09:02     阅读(608)     评论(0)     点赞(14)     收藏(1)


使用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
复制代码

 



所属网站分类: 技术文章 > 博客

作者:听爸爸的话

链接:https://www.pythonheidong.com/blog/article/147983/8a1c1288672ca6f847f7/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

14 0
收藏该文
已收藏

评论内容:(最多支持255个字符)