模拟一个在线音乐播放程序(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 );<br></br>
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');<br></br><br></br>
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