模拟一个在线音乐播放程序(socket + 数据库)
模拟一个在线音乐播放程序(数据库 + socket(TCP协议))
1,使用C/S架构来进行设计,分别写出客户端和服务器程序,
2,客户端链接服务器之后,服务器向用户提示可以选择的歌曲列表,用户选择后开始播放(音频文件存放在本地即可)。不需要实现暂停、切歌等功能
3,需要把常用功能封装为一个工具模块(.py文件),并对其进行调用
1. 创建数据库数据
1 1. 创建数据库 2 create database song; 3 use song; 4 5 2. 创建表 6 create table t_list( 7 id int primary key auto_increment, 8 name varchar(32) not null, 9 link varchar(2000) not null 10 );
11 3. 数据库插入数据(后面的link字段中 需要放音乐文件在电脑上的本地路径,以供后面播放文件时调用) 12 Insert into t_list(name,link) values('stay_with_me', '/Users/.../StayWithMe.mp3'); 13 insert into t_list(name,link) values('Virtual Riot Lift Me_Up', '/Users/.../VirtualRiotLiftMe_Up.mp3'); 14 insert into t_list(name,link) values('阿刁', '/Users/.../阿刁.mp3');
2.在.py文件中 将数据库的功能做一下简单封装(db_helper.py)
1 import pymysql 2 3 4 def get_conn(): # 将数据库的连接做单独封装 5 con = pymysql.connect( 6 host='localhost', 7 user='root', 8 password='123123', 9 db='song', # db的值等于想要查询的数据库名 10 charset='utf8' 11 ) 12 return con 13 14 15 def search_s(sql): # 将查询数据库功能做封装 16 con = get_conn() 17 cursor = con.cursor() 18 cursor.execute(sql) 19 data = cursor.fetchall() 20 return data 21 22 23 def instert_s(sql): # 将插入数据到数据库做封装(本次用不到) 24 con = get_conn() 25 cursor = con.cursor() 26 cursor.execute(sql) 27 con.commit()
3. 编写socket服务器
主要功能:跟socket客户端通信,给客户端发送数据库中歌曲列表,用户选择的歌曲序号,服务器从数据库中查询到对应歌曲的本地路径到客户端
1 from socket import * 2 from db_helper import * # db_helper是上面数据库功能封装后的.py文件名 3 import struct 4 5 6 server = socket() # socket服务器的常规设置 7 server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 8 server.bind(("", 8081)) 9 server.listen(5) 10 11 print('服务器启动...') 12 13 while True: 14 lst = [] 15 total = '' 16 17 newsocket, addr = server.accept() 18 recv_data = newsocket.recv(1024) 19 20 db_data = search_s('select id,name from t_list') # 调用db_helper中的查询方法,从数据库中获取到id和歌名 21 22 for i in db_data: 23 new = str(i[0])+' '+i[1] 24 lst.append(new) 25 26 total = '&'.join(lst) 27 name_len = len(total) 28 29 length = struct.pack('i', name_len) # 将字符串长度通过struct打包后发送到客户端(解决socket服务器沾包问题) 30 newsocket.send(length) 31 newsocket.send(total.encode()) 32 33 select1 = newsocket.recv(1024) 34 s = select1.decode() 35 db_data1 = search_s(f'select link from t_list where id={s}') # 获取到用户选择的歌曲id之后,去数据库中查询对应歌曲的link 36 37 newsocket.send(db_data1[0][0].encode()) # 将link发送到客户端
4. socket客户端
主要功能:跟socket服务器通信,接收服务器发送的数据并打印,发送用户选择的歌曲序号至服务器,获取到link后开始播放本地音乐文件
1 import socket 2 import subprocess 3 import struct 4 5 lst = [] 6 7 client = socket.socket() # socket客户端常规设置 8 client.connect(('127.0.0.1', 8081)) 9 10 while True: 11 client.send('song_list'.encode()) 12 recv_num = client.recv(4) 13 total_size = struct.unpack('i', recv_num)[0] 14 15 recv_size = 0 16 recv_msg = b'' 17 18 while recv_size < total_size: 19 20 every_recv = client.recv(1024) 21 recv_msg += every_recv 22 recv_size += len(every_recv) 23 24 data1 = recv_msg.decode() 25 26 lst1 = data1.split('&') 27 28 for i in lst1: 29 print(i) # 打印从服务器接收到的歌曲列表 30 break 31 32 try: 33 choose = input('请输入ID:').strip() 34 35 client.send(choose.encode()) 36 filename = client.recv(1024).decode() # 获取服务器发送的歌曲本地路径 37 38 print('歌曲播放中...') 39 return_code = subprocess.call(["afplay", filename]) 40 41 client.close() 42 43 except Exception: 44 pass