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:\Users\xu516\PycharmProjects\Python全栈开发\第三模块\网络编程\06_文件传输\client\download'
  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:\Users\xu516\PycharmProjects\Python全栈开发\第三模块\网络编程\06_文件传输\server\share'
 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 >>:

 

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