网络编程(三)

一.大文件的上传下载

server端

 1 import socket
 2 import os
 3 import json
 4 import struct
 5 
 6 server = socket.socket()
 7 server.bind(('127.0.0.1',8080))
 8 server.listen()
 9 
10 while True:
11     conn,addr = server.accept()
12     while True:
13         try:
14             header_len = conn.recv(4)
15             # 解析字典报头
16             header_len = struct.unpack('i',header_len)[0]
17             # 再接收字典数据
18             header_dic = conn.recv(header_len)
19             real_dic = json.loads(header_dic.decode('utf-8'))
20             # 获取数据长度
21             total_size = real_dic.get('file_size')
22             # 循环接收并写入文件
23             recv_size = 0
24             with open(real_dic.get('file_name'),'wb') as f:
25                 while recv_size < total_size:
26                     data = conn.recv(1024)
27                     f.write(data)
28                     recv_size += len(data)
29                 print('上传成功')
30         except ConnectionResetError as e:
31             print(e)
32             break
33     conn.close()

client端

 1 import socket
 2 import json
 3 import os
 4 import struct
 5 
 6 
 7 client = socket.socket()
 8 client.connect(('127.0.0.1',8080))
 9 
10 while True:
11     # 获取电影列表 循环展示
12     MOVIE_DIR = r'D:\python脱产10期视频\day25\视频'
13     movie_list = os.listdir(MOVIE_DIR)
14     # print(movie_list)
15     for i,movie in enumerate(movie_list,1):
16         print(i,movie)
17     # 用户选择
18     choice = input('please choice movie to upload>>>:')
19     # 判断是否是数字
20     if choice.isdigit():
21         # 将字符串数字转为int
22         choice = int(choice) - 1
23         # 判断用户选择在不在列表范围内
24         if choice in range(0,len(movie_list)):
25             # 获取到用户想上传的文件路径
26             path = movie_list[choice]
27             # 拼接文件的绝对路径
28             file_path = os.path.join(MOVIE_DIR,path)
29             # 获取文件大小
30             file_size = os.path.getsize(file_path)
31             # 定义一个字典
32             res_d = {
33                 'file_name':'性感荷官在线发牌.mp4',
34                 'file_size':file_size,
35                 'msg':'注意身体,多喝营养快线'
36             }
37             # 序列化字典
38             json_d = json.dumps(res_d)
39             json_bytes = json_d.encode('utf-8')
40 
41             # 1.先制作字典格式的报头
42             header = struct.pack('i',len(json_bytes))
43             # 2.发送字典的报头
44             client.send(header)
45             # 3.再发字典
46             client.send(json_bytes)
47             # 4.再发文件数据(打开文件循环发送)
48             with open(file_path,'rb') as f:
49                 for line in f:
50                     client.send(line)
51         else:
52             print('not in range')
53     else:
54         print('must be a number')

二.UDP通信

  特点:1.数据宝协议(自带报头)

     2.没有双向通道啊 通信类似于发短信

  好处:1.udp协议客户端允许发空

     2.udp协议不会粘包

        3.udp协议服务端不存在的情况下,客户端照样不会报错

        4.udp协议支持并发

UDP的基本使用

server端

 1 import socket
 2 
 3 
 4 server = socket.socket(type=socket.SOCK_DGRAM)  # UDP协议
 5 server.bind(('127.0.0.1',8080))
 6 # UDP不需要设置半连接池 它也没有半连接池的概念
 7 
 8 # 因为没有双向通道  不需要accept  直接就是通信循环
 9 while True:
10     data, addr = server.recvfrom(1024)
11     print('数据:',data)  # 客户端发来的消息
12     print('地址:',addr)  # 客户端的地址
13     server.sendto(data.upper(),addr)

client端

 1 import socket
 2 
 3 
 4 client = socket.socket(type=socket.SOCK_DGRAM)
 5 # 不需要建立连接  直接进入通信循环
 6 server_address = ('127.0.0.1',8080)
 7 while True:
 8     client.sendto(b'hello',server_address)
 9     data, addr = client.recvfrom(1024)
10     print('服务端发来的数据',data)
11     print('服务端的地址',addr)

三.socketserver

1.用socketserver实现tcp

server端

 1 import socketserver
 2 
 3 
 4 class MyServer(socketserver.BaseRequestHandler):
 5     def handle(self):
 6         # print('来啦 老弟')
 7         while True:
 8             data = self.request.recv(1024)
 9             print(self.client_address)  # 客户端地址
10             print(data.decode('utf-8'))
11             self.request.send(data.upper())
12 
13 
14 if __name__ == '__main__':
15     """只要有客户端连接  会自动交给自定义类中的handle方法去处理"""
16     server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer)  # 创建一个基于TCP的对象
17     server.serve_forever()  # 启动该服务对象

client端

1 import socket
2 
3 client = socket.socket()
4 client.connect(('127.0.0.1',8080))
5 
6 while True:
7     client.send(b'hello')
8     data = client.recv(1024)
9     print(data.decode('utf-8'))

2.用socketserver实现udp

server端

 1 import socketserver
 2 
 3 
 4 class MyServer(socketserver.BaseRequestHandler):
 5     def handle(self):
 6         # print('来啦 老弟')
 7         while True:
 8             data,sock = self.request
 9             print(self.client_address)  # 客户端地址
10             print(data.decode('utf-8'))
11             sock.sendto(data.upper(),self.client_address)
12 
13 
14 if __name__ == '__main__':
15     """只要有客户端连接  会自动交给自定义类中的handle方法去处理"""
16     server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer)  # 创建一个基于TCP的对象
17     server.serve_forever()  # 启动该服务对象

client端

 1 import socket
 2 import time
 3 
 4 client = socket.socket(type=socket.SOCK_DGRAM)
 5 server_address = ('127.0.0.1',8080)
 6 
 7 while True:
 8     client.sendto(b'hello',server_address)
 9     data,addr = client.recvfrom(1024)
10     print(data.decode('utf-8'),addr)
11     time.sleep(1)

 

万般皆下品,唯有读书高!
原文地址:https://www.cnblogs.com/s686zhou/p/11324255.html