需求描述
- 服务器端
- 创建一个 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;
}
@Override
public 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 = "添加";
//包装Data
op.setOp(opWhat);
op.setMusic(music);
//发送Data
oos.writeObject(op);
//接收系统发回的信息
msg = (String) ois.readObject();
System.out.println(msg);
//修改音乐===============================================
opWhat = "修改";
songModify = "青花瓷";
songNew = "七里香";
//包装Data
op.setOp(opWhat);
op.setMusicName(songModify);
op.setMusicNewName(songNew);
//发送Data
oos.writeObject(op);
//接收系统发回的信息
msg = (String) ois.readObject();
System.out.println(msg);
//删除音乐===============================================
opWhat = "删除";
songDelete = "青花瓷";
//包装Data
op.setOp(opWhat);
op.setMusicName(songDelete);
//发送Data
oos.writeObject(op);
//接收系统发回的信息
msg = (String) ois.readObject();
System.out.println(msg);
// 获取播放列表===============================================
opWhat = "查看歌单";
//包装Data
op.setOp(opWhat);
//发送Data
oos.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;
}
@Override
public 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();
}
}
}
}