Python--网络编程-----通过socket收发文件软件开发--面向对象开发

服务端实现

 1 import socket
 2 import struct
 3 import json
 4 import os
 5 
 6 
 7 class MYTCPServer:
 8     address_family = socket.AF_INET
 9     socket_type = socket.SOCK_STREAM
10     allow_reuse_address = False
11     max_packet_size = 8192
12     coding = 'utf-8'
13     request_queue_size = 5
14     server_dir = r'C:\Users\xudachen\PycharmProjects\Python全栈开发\第三模块\网络编程\通过socket发送文件\服务端\file_upload'
15 
16     def __init__(self, server_address, bind_and_active=True):
17         """Constructor. May be extended, do not override"""
18         self.server_address = server_address
19         self.socket = socket.socket(self.address_family, self.socket_type)
20 
21         if bind_and_active:
22             try:
23                 self.server_bind()
24                 self.server_activate()
25             except:
26                 self.server_close()
27                 raise
28 
29     def server_bind(self):
30         """Called by constructor to bind the socket"""
31         if self.allow_reuse_address:
32             self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
33         self.socket.bind(self.server_address)
34         self.server_address = self.socket.getsockname()
35 
36     def server_activate(self):
37         """Called by constructor to activate the server"""
38         self.socket.listen(self.request_queue_size)
39 
40     def server_close(self):
41         """Called to clean-up the server"""
42         self.socket.close()
43 
44     def get_request(self):
45         """Get the request and client address from the socket"""
46         return self.socket.accept()
47 
48     def close_request(self, request):
49         """Called to clean-up an individual request"""
50         request.close()
51 
52     def run(self):
53         while True:
54             self.conn, self.client_addr = self.get_request()
55             print('from client', self.client_addr)
56             while True:
57                 try:
58                     head_struct = self.conn.recv(4)
59                     if not head_struct:
60                         break
61 
62                     head_len = struct.unpack('i', head_struct)[0]
63                     head_json = self.conn.recv(head_len).decode(self.coding)
64                     head_dic = json.loads(head_json)
65 
66                     print(head_dic)
67                     cmd = head_dic['cmd']
68                     if hasattr(self, cmd):
69                         func = getattr(self, cmd)
70                         func(head_dic)
71                 except Exception:
72                     break
73 
74     def put(self, args):
75         file_path = os.path.normpath(os.path.join(self.server_dir, args['filename']))
76 
77         filesize = args['filesize']
78         recv_size = 0
79         print('---->', file_path)
80         with open(file_path, 'wb') as f:
81             while recv_size < filesize:
82                 recv_data = self.conn.recv(self.max_packet_size)
83                 f.write(recv_data)
84                 recv_size += len(recv_data)
85                 print('recvsize:%s filesize:%s' % (recv_size, filesize))
86 
87 
88 tcpserver1 = MYTCPServer(('127.0.0.1', 8080))
89 tcpserver1.run()

客户端实现

 1 import socket
 2 import struct
 3 import json
 4 import os
 5 
 6 
 7 class MYTCPClient:
 8     address_family = socket.AF_INET
 9     socket_type = socket.SOCK_STREAM
10     allow_reuse_address = False
11     max_packet_size = 8192
12     coding = 'utf-8'
13     request_queue_size = 5
14 
15     def __init__(self, server_address, connect=True):
16         self.server_address = server_address
17         self.socket = socket.socket(self.address_family, self.socket_type)
18 
19         if connect:
20             try:
21                 self.client_connect()
22             except:
23                 self.client_close()
24                 raise
25 
26     def client_connect(self):
27         self.socket.connect(self.server_address)
28 
29     def client_close(self):
30         self.socket.close()
31 
32     def run(self):
33         while True:
34             inp = input(">>:").strip()  # put test.py
35             if not inp:
36                 continue
37             l = inp.split()  # ['put','test.py']
38             cmd = l[0]  # put
39             if hasattr(self, cmd):
40                 func = getattr(self, cmd)
41                 func(l)
42 
43     def put(self, args):  # ['put','test.py']
44         cmd = args[0]  # put
45         filename = args[1]  # test.py
46         if not os.path.isfile(filename):
47             print('file:%s is not exists' % filename)
48             return
49         else:
50             filesize = os.path.getsize(filename)
51 
52         head_dic = {'cmd': cmd,
53                     'filename': os.path.basename(filename),
54                     'filesize': filesize}
55         print(head_dic)
56         head_json = json.dumps(head_dic)
57         head_json_bytes = bytes(head_json, encoding=self.coding)
58 
59         head_struct = struct.pack('i', len(head_json_bytes))
60         self.socket.send(head_struct)
61         self.socket.send(head_json_bytes)
62         send_size = 0
63         with open(filename, 'rb') as f:
64             for line in f:
65                 self.socket.send(line)
66                 send_size += len(line)
67                 print(send_size)
68             else:
69                 print('upload successful')
70 
71 
72 client = MYTCPClient(('127.0.0.1', 8080))
73 client.run()

先启动服务端,再启动客户端,在客户端输入put test.py

客户端运行结果为;

 1 >>:put test.py
 2 {'cmd': 'put', 'filename': 'test.py', 'filesize': 1014}
 3 17
 4 20
 5 61
 6 83
 7 86
 8 128
 9 140
10 142
11 187
12 201
13 241
14 253
15 255
16 268
17 294
18 313
19 328
20 354
21 386
22 398
23 400
24 413
25 416
26 440
27 443
28 477
29 489
30 504
31 507
32 536
33 593
34 632
35 651
36 687
37 723
38 779
39 805
40 807
41 822
42 856
43 877
44 879
45 894
46 896
47 955
48 988
49 1014
50 upload successful
51 >>:

服务端运行结果:

1 from client ('127.0.0.1', 55771)
2 {'cmd': 'put', 'filename': 'test.py', 'filesize': 1014}
3 ----> C:\Users\xudachen\PycharmProjects\Python全栈开发\第三模块\网络编程\通过socket发送文件\服务端\file_upload\test.py
4 recvsize:1014 filesize:1014

实际效果:

注意,在windows系统中使用pycharm,上传成功后,并不会立即在上传文件夹中显示,需要找到文件夹路径,点进去,然后才会在pycharm中看到,

 

posted @ 2018-04-16 11:52  xudachen  阅读(586)  评论(0编辑  收藏  举报