Python--网络编程-----文件传输优化版本

一、服务端代码为:

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

二、客户端代码为:

 1 import socket
 2 import struct
 3 import json
 4 
 5 download_dir = r'C:\Users\xu516\PycharmProjects\Python全栈开发\第三模块\网络编程\06_文件传输\优化版本_写函数\client\download'
 6 
 7 
 8 def get(phone, cmds):
 9     # 2、以写的方式打开一个新文件,接收服务器端发来的文件内容写入客户的新文件
10 
11     # 第一步:先收报头的长度
12     obj = phone.recv(4)
13     header_size = struct.unpack('i', obj)[0]
14 
15     # 第二步:再收报头
16     header_bytes = phone.recv(header_size)
17 
18     # 第三步:从报头中解析出对真实数据的描述信息
19     header_json = header_bytes.decode('utf-8')
20     header_dic = json.loads(header_json)
21     print(header_dic)
22     total_size = header_dic['file_size']
23     filename = header_dic['filename']
24 
25     # 第四步: 接收真实的数据
26     with open('%s\%s' % (download_dir, filename), 'wb') as f:
27         recv_size = 0
28         while recv_size < total_size:
29             line = phone.recv(1024)
30             f.write(line)
31             recv_size += len(line)
32             print('总大小:%s  已下载大小:%s' % (total_size, recv_size))
33 
34 
35 def put(phone, cmds):
36     pass
37 
38 
39 def run():
40     phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
41     phone.connect(('127.0.0.1', 8081))
42 
43     while True:
44         # 1、发命令
45         inp = input('>>:').strip()  # get a.txt
46         if not inp:
47             continue
48         phone.send(inp.encode('utf-8'))
49 
50         cmds = inp.split()  # ['get', 'a.txt']
51         if cmds[0] == 'get':
52             get(phone, cmds)
53         elif cmds[0] == 'put':
54             put(phone, cmds)
55 
56     phone.close()
57 
58 
59 if __name__ == '__main__':
60     run()

先启动服务端,在启动客户端,在客户端输入get test.py 下载成功:

客户端运行结果为:

1 >>:get test.py
2 {'filename': 'test.py', 'md5': 'xxdxx', 'file_size': 60}
3 总大小:60  已下载大小:60
4 >>:

 

posted @ 2018-04-09 23:43  xudachen  阅读(238)  评论(0编辑  收藏  举报