网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例
Posted ludingchao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例相关的知识,希望对你有一定的参考价值。
UDP协议 (了解)
称之为数据包协议。
特点:
1) 不需要建立链接。
2) 不需要知道对方是否收到。
3) 数据不安全
4) 传输速度快
5)能支持并发
6) 不会粘包
7) 无需先启动服务端再启动客户端
优点:
- 传输速度快
- 能支持并发
- 不会粘包
缺点:
- 数据不安全, 容易丢失
应用场景: 早期的QQ聊天室。
# server端 import socket # socket.SOCK_DGRAM ---> UPD协议 server = socket.socket(type=socket.SOCK_DGRAM) # 服务端需要绑定一个地址,让别人知道你在哪里 server.bind( (‘127.0.0.1‘, 9002) ) while True: # 发送数据给服务端的用户地址 data, addr = server.recvfrom(1024) print(addr) print(data) # msg = input(‘Server ---> Client:‘).encode(‘utf-8‘) # 无论服务端还是客户端,发送消息时,都必须知道对方是谁 # server.sendto(msg, addr)
# client端 import socket client = socket.socket(type=socket.SOCK_DGRAM) address = (‘127.0.0.1‘, 9002) while True: msg = input(‘Client ---> Server:‘).encode(‘utf-8‘) client.sendto(msg, address) # data, addr = client.recvfrom(1024) # # print(data)
- TCP协议(称为流式协议):
优点:
- 数据安全
缺点:
- 传输速度慢
- 粘包
面试: TCP与UDP的区别, 简述优缺点即可。(*******)
TCP局域网客户端与服务端上传下载电影示例
文件夹位置:
‘‘‘ server 6.实现需求 - 准备一堆电影,存放在一个文件夹中。 - 需求: - 1)客户端上传到服务端 1.让用户选择的上传的电影 2.服务端接收电影并保存 - 2)客户端下载服务端中的电影 1.客户端让服务端返回可下载电影 2.客户端选择下载的电影并下载 ‘‘‘ import socket import struct import json import os movie_path = r‘D:oldboy_edupython课堂内容day291 作业讲解server_movie‘ def recv(conn): headers = conn.recv(4) bytes_len = struct.unpack(‘i‘, headers)[0] json_data = conn.recv(bytes_len).decode(‘utf8‘) back_dic = json.loads(json_data) print(‘收到服务端数据: ‘, back_dic) return back_dic def send(msg,conn): json_bytes = json.dumps(msg).encode(‘utf8‘) headers = struct.pack(‘i‘, len(json_bytes)) conn.send(headers) conn.send(json_bytes) server = socket.socket() server.bind((‘127.0.0.1‘,9000)) server.listen(5) while True: conn,addr = server.accept() while True: try: # 1、接收客户端发送的消息 back_dic=recv(conn) _type = back_dic.get(‘type‘) if _type == ‘upload‘: # 4.组织服务端存放上传电影的目录 movie_size = back_dic.get(‘movie_size‘) movie_name = back_dic.get(‘movie_name‘) download_path = r‘D:oldboy_edupython课堂内容day291 作业讲解server_save_movie‘ # 保存电影文件路径 movie_download_path = os.path.join(download_path,movie_name) recv_data = 0 with open(movie_download_path,‘wb‘)as f: # 一次性接收电影所有数据,有可能撑爆内存 # movie_data = conn.recv(movie_size) # f.write(movie_data) # 一点一点接收 while recv_data < movie_size: data = conn.recv(1024) f.write(data) recv_data+=len(data) elif _type == ‘download‘: movie_list = os.listdir(movie_path) send_dic = {‘movie_list‘:movie_list} # 服务端发送给客户端的字典 send(send_dic, conn) # 服务端接收客户端发送过来的字典 back_dic=recv(conn) movie_name = back_dic.get(‘movie_name‘) # 拼接需要下载的电影文件路径 movie_choose_path = os.path.join(movie_path,movie_name) movie_size= os.path.getsize(movie_choose_path) # 组织需要发送给客户端的电影数据 send_dic = {‘movie_size‘:movie_size} send(send_dic,conn) # json数据发送完毕后,紧接着发送真实电影数据 with open(movie_choose_path,‘rb‘)as f: for line in f: conn.send(line) except Exception as e: print(e) break conn.close()
# client import socket import struct import json import os client = socket.socket() client.connect((‘127.0.0.1‘,9000)) movie_path = r‘D:oldboy_edupython课堂内容day291 作业讲解client_movie‘ def send(msg,client): json_bytes = json.dumps(msg).encode(‘utf8‘) headers = struct.pack(‘i‘, len(json_bytes)) client.send(headers) client.send(json_bytes) def recv(client): headers = client.recv(4) bytes_len = struct.unpack(‘i‘, headers)[0] json_data = client.recv(bytes_len).decode(‘utf8‘) back_dic = json.loads(json_data) print(‘收到服务端数据: ‘, back_dic) return back_dic while True: # 打印功能编号,让用户选择功能 print(‘‘‘ 1.上传 2.下载 q.退出 ‘‘‘) choice = input(‘请输入功能编号:‘).strip() if choice == ‘q‘: break elif choice == ‘1‘: # 1) 组织报头数据,并打包 # 上传电影功能 movie_list = os.listdir(movie_path) while True: for index,movie_name in enumerate(movie_list): print(index,movie_name) choice = input(‘输入需要上传的电影编号:‘).strip() if not choice.isdigit(): continue choice = int(choice) if not choice in range(len(movie_list)): continue movie_name = movie_list[choice] # 拼接上传电影的路径 upload_movie_path= os.path.join(movie_path,movie_name) # os.path.getsize(): 获取文件大小 movie_size = os.path.getsize(upload_movie_path) # 客户端发送给服务端的字典 send_dic = { ‘type‘:‘upload‘, ‘movie_name‘:movie_name, ‘movie_size‘:movie_size } send(send_dic,client) # 开始发送上传的电影 with open(upload_movie_path,‘rb‘)as f: # 一次性发送: 内存资源占用过大 # data = f.read() # client.send(data) # 一点一点发送 for line in f: client.send(line) elif choice == ‘2‘: # 下载电影功能 # 1.客户端发送消息给服务端 send_dic = {‘type‘:‘download‘} send(send_dic,client) # 2.客户端接收服务端返回的消息 back_dic=recv(client) movie_list = back_dic.get(‘movie_list‘) # 4.循环打印需要下载的电影列表 while True: for index,movie_name in enumerate(movie_list): print(index,movie_name) choice = input(‘请输入上传电影编号:‘).strip() if not choice.isdigit(): continue choice = int(choice) if choice not in range(len(movie_list)): continue movie_name = movie_list[choice] # 发送需要下载电影的字典给服务端 send_dic = {‘movie_name‘:movie_name} send(send_dic,client) # 客户端接收服务单发送过来的电影字典 back_dic = recv(client) # 接收电影的数据大小 movie_size = back_dic.get(‘movie_size‘) movie_save_path = os.path.join(movie_path,movie_name) recv_data = 0 # 开始接收真实电影数据 with open (movie_save_path,‘wb‘)as f: while recv_data < movie_size: data = client.recv(1024) f.write(data) recv_data += len(data) client.close()
以上是关于网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例的主要内容,如果未能解决你的问题,请参考以下文章