需求描述
- 服務器端
- 創建一個 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();}}}
}