当前位置: 首页 > news >正文

TCP基础题:音乐播放列表管理系统

需求描述

  • 服务器端
    • 创建一个 TCP 服务器,监听本地的 9999 端口,支持多个客户端连接。
    • 维护一个音乐播放列表,每个音乐条目包含歌曲名称、歌手、时长等信息。
    • 能够处理客户端的以下请求:
      • 添加音乐到播放列表:接收客户端发送的 Music 对象,使用 ObjectInputStream 读取,并将其添加到播放列表中。
      • 删除音乐:接收客户端发送的歌曲名称,使用 ObjectInputStream 读取,从播放列表中删除对应歌曲。
      • 获取播放列表:将当前的播放列表封装成 MusicPlaylist 对象,使用 ObjectOutputStream 发送给客户端。
  • 客户端
    • 创建一个 TCP 客户端,连接到本地的 9999 端口。
    • 可以向服务器发送添加音乐请求,创建 Music 对象并使用 ObjectOutputStream 发送。
    • 可以向服务器发送删除音乐请求,将歌曲名称使用 ObjectOutputStream 发送。
    • 可以向服务器发送获取播放列表请求,接收服务器返回的 MusicPlaylist 对象,使用 ObjectInputStream 读取并显示。
数据描述
  • Music 类
    • String songName:歌曲名称。
    • String singer:歌手。
    • int duration:歌曲时长(秒)。
  • MusicPlaylist 类
    • ArrayList<Music> musicList:音乐播放列表。

 附加:修改歌单名字

Server和Client的Music,Data和MusicPlaylist类 

        music类

import java.io.Serializable;public class Music implements Serializable {private String songName;private String singer;private int duration;public Music(String songName, String singer, int duration) {this.songName = songName;this.singer = singer;this.duration = duration;}public String getSongName() {return songName;}public String getSinger() {return singer;}public int getDuration() {return duration;}public void setSongName(String songName) {this.songName=songName;}public void setSinger(String singer) {this.singer=singer;}public void setDuration(int duration) {this.duration=duration;}@Overridepublic String toString() {return "歌曲名称: " + songName + ", 歌手: " + singer + ", 时长: " + duration + " 秒";}
}

        MusicPlaylist类

import java.io.Serializable;
import java.util.ArrayList;public class MusicPlaylist implements Serializable {private ArrayList<Music> musicList;public MusicPlaylist() {this.musicList = new ArrayList<>();}public ArrayList<Music> getMusicList() {return musicList;}public void addMusic(Music music) {musicList.add(music);}public void removeMusic(String songName) {musicList.removeIf(music -> music.getSongName().equals(songName));}public void modifyMusic(String songModify, String songNew){for (Music music : musicList) {if (music.getSongName().equals(songModify)){music.setSongName(songNew);}}}
}

        Data类(Data类启到一个把用户操作封装的作用,便于数据的打包和传输,方便程序编写的使用)

import java.io.Serializable;public class Data implements Serializable {private String op;private String songName;private String songNew;private Music music;public Data() {}public Data(String op) {this.op=op;}public String getOp() {return op;}public void setOp(String op) {this.op=op;}public Music getMusic() {return music;}public void setMusic(Music music) {this.music=music;}public void setMusicName(String songName) {this.songName = songName;}public String getMusicName() {return songName;}public void setMusicNewName(String songNew) {this.songNew = songNew;}public String getMusicNewName() {return songNew;}
}

客户端ClientZJL:

import com.zb2.entity.Data;
import com.zb2.entity.Music;
import com.zb2.entity.MusicPlaylist;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;public class ClientZJL {public static void main(String[] args) throws IOException, ClassNotFoundException {Socket socket = new Socket("127.0.0.1", 9999);ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());String opWhat;String songDelete;String songModify;String songNew;String msg;Data op = new Data();// 添加音乐===============================================Music music = new Music("青花瓷", "周杰伦", 300);opWhat = "添加";//包装Dataop.setOp(opWhat);op.setMusic(music);//发送Dataoos.writeObject(op);//接收系统发回的信息msg = (String) ois.readObject();System.out.println(msg);//修改音乐===============================================opWhat = "修改";songModify = "青花瓷";songNew = "七里香";//包装Dataop.setOp(opWhat);op.setMusicName(songModify);op.setMusicNewName(songNew);//发送Dataoos.writeObject(op);//接收系统发回的信息msg = (String) ois.readObject();System.out.println(msg);//删除音乐===============================================opWhat = "删除";songDelete = "青花瓷";//包装Dataop.setOp(opWhat);op.setMusicName(songDelete);//发送Dataoos.writeObject(op);//接收系统发回的信息msg = (String) ois.readObject();System.out.println(msg);// 获取播放列表===============================================opWhat = "查看歌单";//包装Dataop.setOp(opWhat);//发送Dataoos.writeObject(op);//接收系统发回的歌单对象MusicPlaylist playlist = (MusicPlaylist) ois.readObject();//将歌单对象转换为集合并打印ArrayList<Music> musicList = playlist.getMusicList();for (Music m : musicList) {System.out.println(m);}}
}

服务端Server:

        Server类

import com.zb2.entity.MusicPlaylist;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(9999);System.out.println("服务器启动 端口:" + 9999);MusicPlaylist playlist = new MusicPlaylist();while (true) {Socket socket=serverSocket.accept();ServerThread serverThread = new ServerThread(socket, playlist);serverThread.start();}}
}

        ServerThread类

import com.zb2.entity.Data;
import com.zb2.entity.MusicPlaylist;import java.io.*;
import java.net.Socket;public class ServerThread extends Thread {private Socket socket;private MusicPlaylist playlist;public ServerThread(Socket socket, MusicPlaylist playlist) {this.socket = socket;this.playlist = playlist;}@Overridepublic void run() {ObjectInputStream ois =null;ObjectOutputStream oos =null;try {ois=new ObjectInputStream(socket.getInputStream());oos=new ObjectOutputStream(socket.getOutputStream());Data op = new Data();op =(Data) ois.readObject();switch (op.getOp()) {case "添加":playlist.addMusic(op.getMusic());System.out.println("添加音乐: " + op.getMusic());oos.writeObject("添加成功!");break;case "删除":playlist.removeMusic(op.getMusicName());System.out.println("删除音乐: " + op.getMusicName());oos.writeObject("删除成功!");break;case "修改":playlist.modifyMusic(op.getMusicName(),op.getMusicNewName());System.out.println("修改音乐: " + op.getMusicName()+",为"+op.getMusicNewName());oos.writeObject("修改成功!");break;case "查看歌单":oos.writeObject(playlist);System.out.println("返回给客户端歌单");break;}} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}finally {try {oos.close();ois.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}
}

运行结果:

添加歌曲:

查看歌单:

删除歌曲(青花瓷):

再次查看歌单:

修改曲目(青花瓷->七里香):

再次查看歌单:

相关文章:

  • React 的 useEffect 清理函数详解
  • Docker-高级使用
  • 【python】Python 中,单下划线(_)和双下划线(__)开头以及结尾的命名方式具有特殊的含义和用途
  • 安恒web安全春招实战
  • 如何使用 Apache 配置用户主页 ?
  • 【前端】【面试】在前端开发中,如何优化 CSS 以提升页面渲染性能?
  • 轻松完成视频创作,在线视频编辑器,无需下载软件,功能多样实用!
  • 游戏引擎学习第243天:异步纹理下载
  • C++区别于C语言的提升用法(万字总结)
  • 推荐几个可以免费下载视频的软件(Neat Download Manager、蜗牛下载助手、bilidown)
  • 【安全扫描器原理】网络扫描算法
  • 【题解-Acwing】851. spfa求最短路
  • 动态自适应分区算法(DAPS)设计流程详解
  • 【Qt6 QML Book 基础】07:布局项 —— 锚定布局与动态交互(附完整可运行代码)
  • MySQL 报错解析:SQLSyntaxErrorException caused by extra comma before FROM
  • 网络原理 - 7(TCP - 4)
  • 技术视界 | 数据的金字塔:从仿真到现实,机器人学习的破局之道
  • EFISH-SBC-RK3588无人机地面基准站项目
  • 【Hive入门】Hive查询语言(DQL)完全指南:从基础查询到高级分析
  • 基于 EFISH-SBC-RK3588 的无人机通信云端数据处理模块方案‌
  • 今年五一,贵州一脸“爆相”
  • 技术派|“会飞的手榴弹”:微型无人机将深刻改变单兵作战方式
  • 第四届全民阅读大会在太原举办,李书磊出席并讲话
  • 特写|“三峡千古情”出圈,一场演出给宜昌留下更多游客
  • 推进“三个免于”,上海试点首发进口化妆品快速通关模式
  • 特朗普激发加拿大爱国热情之下:大选提前投票人数创纪录,魁北克分离情绪被冲淡