zoukankan      html  css  js  c++  java
  • Python--网络编程-----文件传输简单版本

    一、服务端代码:

     1 import socket
     2 import subprocess
     3 import struct
     4 import json
     5 import os
     6 
     7 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     8 # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     9 phone.bind(('127.0.0.1', 8081))  # 0-65535:0-1024给操作系统使用
    10 phone.listen(5)
    11 
    12 print('starting......')
    13 while True:  # 链接循环
    14     conn, client_addr = phone.accept()
    15     print(client_addr)
    16 
    17     while True:  # 通信循环
    18         try:
    19             # 1、收命令
    20             res = conn.recv(8096)  # b'get a.txt'
    21             if not res:  # 适用于linux操作系统
    22                 break
    23 
    24             # 2、解析命令,提取相应命令参数
    25             cmds = res.decode('utf-8').split()  # ['get', 'a.txt']
    26             filename = cmds[1]
    27             # 3、以读的方式打开文件,读取文件内容发送到客户端
    28 
    29             # 第一步:制作固定长度的报头
    30             header_dic = {
    31                 'filename': filename,
    32                 'md5': 'xxdxx',
    33                 'file_size': os.path.getsize(filename)
    34             }
    35 
    36             header_json = json.dumps(header_dic)
    37             header_bytes = header_json.encode('utf-8')
    38 
    39             # 第二步:先发送报头的长度
    40             conn.send(struct.pack('i', len(header_bytes)))
    41 
    42             # 第三步:把包头发送给客户端
    43             conn.send(header_bytes)
    44 
    45             # 第三步:再发送真实的数据
    46             with open(filename, 'rb') as f:
    47                 # conn.send(f.read())
    48                 for line in f:
    49                     conn.send(line)
    50 
    51         except ConnectionResetError:  # 适用于Windows操作系统
    52             break
    53 
    54     conn.close()
    55 
    56 phone.close()

    二、客户端代码:

     1 import socket
     2 import struct
     3 import json
     4 
     5 
     6 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     7 
     8 phone.connect(('127.0.0.1', 8081))
     9 
    10 while True:
    11     # 1、发命令
    12     cmd = input('>>:').strip()  # get a.txt
    13     if not cmd:
    14         continue
    15     phone.send(cmd.encode('utf-8'))
    16 
    17     # 2、以写的方式打开一个新文件,接收服务器端发来的文件内容写入客户的新文件
    18 
    19     # 第一步:先收报头的长度
    20     obj = phone.recv(4)
    21     header_size = struct.unpack('i', obj)[0]
    22 
    23     # 第二步:再收报头
    24     header_bytes = phone.recv(header_size)
    25 
    26     # 第三步:从报头中解析出对真实数据的描述信息
    27     header_json = header_bytes.decode('utf-8')
    28     header_dic = json.loads(header_json)
    29     print(header_dic)
    30     total_size = header_dic['file_size']
    31     filename = header_dic['filename']
    32 
    33     # 第四步: 接收真实的数据
    34     with open(filename, 'wb') as f:
    35         recv_size = 0
    36         while recv_size < total_size:
    37             line = phone.recv(1024)
    38             f.write(line)
    39             recv_size += len(line)
    40 
    41 
    42 phone.close()

    先启动服务端,再启动客户端,然后在客户端执行 get 1.txt, get test.py  都显示下载成功:

    客户端打印字典信息为:

    1 >>:get 1.txt
    2 {'filename': '1.txt', 'md5': 'xxdxx', 'file_size': 8}
    3 >>:get test.py
    4 {'filename': 'test.py', 'md5': 'xxdxx', 'file_size': 60}
    5 >>:

    以上代码已经实现了客户端从服务端下载文件的功能,如果想把数据从客户端上传到服务端,则把服务端和客户端代码

    做相应调整即可。

    如果server提供下载文件夹share,client指定下载文件夹download,

    客户端和服务端代码改为:

      1 客户端代码:
      2 import socket
      3 import struct
      4 import json
      5 
      6 download_dir = r'C:Usersxu516PycharmProjectsPython全栈开发第三模块网络编程6_文件传输clientdownload'
      7 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      8 
      9 phone.connect(('127.0.0.1', 8081))
     10 
     11 while True:
     12     # 1、发命令
     13     cmd = input('>>:').strip()  # get a.txt
     14     if not cmd:
     15         continue
     16     phone.send(cmd.encode('utf-8'))
     17 
     18     # 2、以写的方式打开一个新文件,接收服务器端发来的文件内容写入客户的新文件
     19 
     20     # 第一步:先收报头的长度
     21     obj = phone.recv(4)
     22     header_size = struct.unpack('i', obj)[0]
     23 
     24     # 第二步:再收报头
     25     header_bytes = phone.recv(header_size)
     26 
     27     # 第三步:从报头中解析出对真实数据的描述信息
     28     header_json = header_bytes.decode('utf-8')
     29     header_dic = json.loads(header_json)
     30     print(header_dic)
     31     total_size = header_dic['file_size']
     32     filename = header_dic['filename']
     33 
     34     # 第四步: 接收真实的数据
     35     with open('%s\%s' % (download_dir, filename), 'wb') as f:
     36         recv_size = 0
     37         while recv_size < total_size:
     38             line = phone.recv(1024)
     39             f.write(line)
     40             recv_size += len(line)
     41             print('总大小:%s  已下载大小:%s' % (total_size, recv_size))
     42 
     43 
     44 phone.close()
     45 
     46 服务端代码:
     47 import socket
     48 import subprocess
     49 import struct
     50 import json
     51 import os
     52 
     53 share_dir = r'C:Usersxu516PycharmProjectsPython全栈开发第三模块网络编程6_文件传输servershare'
     54 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     55 # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     56 phone.bind(('127.0.0.1', 8081))  # 0-65535:0-1024给操作系统使用
     57 phone.listen(5)
     58 
     59 print('starting......')
     60 while True:  # 链接循环
     61     conn, client_addr = phone.accept()
     62     print(client_addr)
     63 
     64     while True:  # 通信循环
     65         try:
     66             # 1、收命令
     67             res = conn.recv(8096)  # b'get a.txt'
     68             if not res:  # 适用于linux操作系统
     69                 break
     70 
     71             # 2、解析命令,提取相应命令参数
     72             cmds = res.decode('utf-8').split()  # ['get', 'a.txt']
     73             filename = cmds[1]
     74             # 3、以读的方式打开文件,读取文件内容发送到客户端
     75 
     76             # 第一步:制作固定长度的报头
     77             header_dic = {
     78                 'filename': filename,
     79                 'md5': 'xxdxx',
     80                 'file_size': os.path.getsize('%s\%s' % (share_dir, filename))
     81             }
     82 
     83             header_json = json.dumps(header_dic)
     84             header_bytes = header_json.encode('utf-8')
     85 
     86             # 第二步:先发送报头的长度
     87             conn.send(struct.pack('i', len(header_bytes)))
     88 
     89             # 第三步:把包头发送给客户端
     90             conn.send(header_bytes)
     91 
     92             # 第三步:再发送真实的数据
     93             with open('%s\%s' % (share_dir, filename), 'rb') as f:
     94                 # conn.send(f.read())
     95                 for line in f:
     96                     conn.send(line)
     97 
     98         except ConnectionResetError:  # 适用于Windows操作系统
     99             break
    100 
    101     conn.close()
    102 
    103 phone.close()

     客户端下载 get  test.py 运行结果为:

    1 >>:get test.py
    2 {'filename': 'test.py', 'md5': 'xxdxx', 'file_size': 60}
    3 总大小:60  已下载大小:60
    4 >>:
  • 相关阅读:
    POJ 3276 Face The Right Way
    POJ 3061 Subsequence
    HDU 2104 hide handkerchief
    GCJ Crazy Rows
    HDU 1242 Rescue
    激光炸弹:二维前缀和
    I Hate It:线段树:单点修改+区间查询
    承压计算:模拟+double
    等差素数列:线性筛+枚举
    Period :KMP
  • 原文地址:https://www.cnblogs.com/xudachen/p/8763491.html
Copyright © 2011-2022 走看看