Ella_Wu

坚持你应该坚持的

模拟一个在线音乐播放程序(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
posted @ 2020-01-16 10:43  Ella_Wu  阅读(763)  评论(0编辑  收藏  举报