客戶端:服務器
通訊格式:
1) 下載文件消息格式:@action=Download["fileName":"fileSize":"result"]
參數說明:
fileName 要下載的文件的名字
fileSize 要下載的文件的大小
result 下載許可
2) 上傳文件消息格式: @action=Upload["fileName":"fileSize":result]
參數說明:
fileName 要上傳的文件的名字
* fileSize 要上傳的文件的大小
result 上傳許可
3)返回文件列表格式
*; @action=GroupFileList["fileName1":"fileName2":"fileName3"...]
複製代碼
服務端:socket
public class FileServer {
private final int port = 5203;
private ServerSocket server_socket; //普通消息傳輸服務器套接字
private ServerSocket fileServerSocket; // 文件傳輸服務器套接字
private String path ="文件服務器/GroupFile"; //服務器文件保存路徑
public FileServer() {
try {
//1-初始化
server_socket = new ServerSocket(this.port); // 建立消息傳輸服務器
fileServerSocket = new ServerSocket(8888); //建立文件傳輸服務器
System.out.println("文件服務器啓動等待客戶端鏈接.....");
//2-每次接收一個客戶端請求鏈接時都啓用一個線程處理
while(true) {
Socket client_socket = server_socket.accept();
System.out.println("客戶端:"+client_socket.getRemoteSocketAddress()+"已鏈接");
new ServerThread(client_socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/** ----------------------------------------------------------------------------------------------------- * * 啓用一個線程處理客戶端的請求 */
private class ServerThread extends Thread{
private Socket client_socket;
private BufferedReader server_in;
private PrintWriter server_out;
public ServerThread(Socket client_socket) {
try {
//初始化
this.client_socket = client_socket;
server_in = new BufferedReader(new InputStreamReader(this.client_socket.getInputStream()));
server_out = new PrintWriter(this.client_socket.getOutputStream(),true);
} catch (IOException e) {
}
}
public void run() {
try {
String uploadFileName = null;
String uploadFileSize = null;
String fromClientData ;
while((fromClientData = server_in.readLine()) != null){
//把服務器文件列表返回
if(fromClientData.startsWith("@action=loadFileList")){
File dir = new File(path);
if (dir.isDirectory()){
String[] list = dir.list();
String filelist = "@action=GroupFileList[";
for (int i = 0; i < list.length; i++) {
if (i == list.length-1){
filelist = filelist + list[i]+"]";
}else {
filelist = filelist + list[i]+":";
}
}
server_out.println(filelist);
}
}
//請求上傳文件
if (fromClientData.startsWith("@action=Upload")){
uploadFileName = ParseDataUtil.getUploadFileName(fromClientData);
uploadFileSize = ParseDataUtil.getUploadFileSize(fromClientData);
File file = new File(path,uploadFileName);
//文件是否已存在
if (file.exists()){
//文件已經存在無需上傳
server_out.println("@action=Upload[null:null:NO]");
}else {
//通知客戶端開能夠上傳文件
server_out.println("@action=Upload["+uploadFileName+":"+uploadFileSize+":YES]");
//開啓新線程上傳文件
new HandleFileThread(1,uploadFileName,uploadFileSize).start();
}
}
//請求下載文件
if(fromClientData.startsWith("@action=Download")){
String fileName = ParseDataUtil.getDownFileName(fromClientData);
File file = new File(path,fileName);
if(!file.exists()){
server_out.println("@action=Download[null:null:文件不存在]");
}else {
//通知客戶端開能夠下載文件
server_out.println("@action=Download["+file.getName()+":"+file.length()+":OK]");
//開啓新線程處理下載文件
new HandleFileThread(0,file.getName(),file.length()+"").start();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/** * 文件傳輸線程 */
class HandleFileThread extends Thread{
private String filename;
private String filesize;
private int mode; //文件傳輸模式
public HandleFileThread(int mode,String name,String size){
filename = name;
filesize = size;
this.mode = mode;
}
public void run() {
try {
Socket socket = fileServerSocket.accept();
//上傳文件模式
if(mode == 1){
//開始接收上傳
BufferedInputStream file_in = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(path,filename)));
int len;
byte[] arr = new byte[8192];
while ((len = file_in.read(arr)) != -1){
bos.write(arr,0,len);
bos.flush();
}
server_out.println("@action=Upload[null:null:上傳完成]");
server_out.println("\n");
bos.close();
}
//下載文件模式
if(mode == 0){
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(path,filename)));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
System.out.println("服務器:開始下載");
int len;
byte[] arr =new byte[8192];
while((len = bis.read(arr)) != -1){
bos.write(arr,0,len);
bos.flush();
}
socket.shutdownOutput();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//啓動程序
public static void main(String[] args) {
new FileServer();
}
}
複製代碼
public class GroupFileView extends JFrame {
private int width = 400;
private int height = 600;
private JLabel groupLabel;
private JButton uploadButton;
private JLabel flushLabel;
private String fileIconPath = "文件客戶端/resource/file-min.png";
private JScrollPane jScrollPane;
private JPanel staffPanel; //在JSpanel上的panel
private Socket client_socket;
private PrintStream client_out;
private BufferedReader client_in;
private String ip = "127.0.0.1";
private int port = 5203;
private File currentUpploadFile;
private String downloadSavePath;
private int Y = 0;
public GroupFileView() {
//1-初始化
initVariable();
//2-鏈接服務器
connectServer();
//3-註冊監聽
registerListener();
//4-初始化窗口設置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(width,height);
this.setTitle("羣文件");
this.setLocationRelativeTo(null);//窗口居中顯示
this.setResizable(false);
this.setVisible(true);
}
private void initVariable() {
jScrollPane = new JScrollPane();
this.getContentPane().add(jScrollPane);
staffPanel = new JPanel();
///staffPanel.setLayout(new BoxLayout(staffPanel,BoxLayout.Y_AXIS));
staffPanel.setLayout(null);
staffPanel.setOpaque(false);
staffPanel.setPreferredSize(new Dimension(width,height));
jScrollPane.setViewportView(staffPanel);
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//設置水平滾動條隱藏
jScrollPane.getViewport().setOpaque(false); //設置透明
jScrollPane.setOpaque(false); //設置透明
renderTop();
}
/** * 向服務器從新讀取羣文件列表 */
private void loadGroupFile() {
client_out.println("@action=loadFileList");
}
/** * 渲染頂部面板 */
private void renderTop(){
staffPanel.removeAll();
Y = 0;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1,3,3,10));
this.groupLabel = new JLabel("\t\t\t\t\t羣文件列表 ");
this.uploadButton = new JButton("上傳文件 ");
flushLabel = new JLabel(new ImageIcon("聊天室客戶端/resource/flush.png"));
panel.add(groupLabel);
panel.add(uploadButton);
panel.add(flushLabel);
panel.setBounds(2,Y,width,30);
this.staffPanel.add(panel);
Y += 30;
}
/** 渲染文件列表 */
public void addToFileList(String filename){
JLabel fileicon = new JLabel(new ImageIcon(fileIconPath));
JButton downloadBtn = new JButton("下載");
JLabel fileNameLab = new JLabel(filename);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1,3,0,0));
panel.add(fileicon);
panel.add(fileNameLab);
panel.add(downloadBtn);
//panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.setBounds(2,Y,width,30);
this.staffPanel.add(panel);
Y+=30;
panel.addMouseListener(new MouseAdapter() {
//鼠標移入時
public void mouseEntered(MouseEvent e) { // 鼠標移動到這裏的事件
panel.setBackground(Color.orange);
panel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // 讓鼠標移動到
}
public void mouseExited(MouseEvent e) { // 鼠標離開的事件
panel.setBackground(Color.white);
}
});
//文件下載
downloadBtn.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
//1-選擇下載保存的位置
JFileChooser f = new JFileChooser(); // 查找文件
f.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
f.showOpenDialog(null);
File file = f.getSelectedFile();
if(file != null){
downloadSavePath = file.getPath();
//向服務器請求下載
client_out.println("@action=Download["+filename+":null:null]");
}
}
});
}
/** * 註冊監聽 */
private void registerListener() {
//上傳文件 消息格式: @action=Upload["fileName":"fileSize":result]
this.uploadButton.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
JFileChooser f = new JFileChooser(); // 查找文件
f.showOpenDialog(null);
currentUpploadFile = f.getSelectedFile();
if(currentUpploadFile != null)
client_out.println("@action=Upload["+currentUpploadFile.getName()+":"+currentUpploadFile.length()+":null]");
}
});
//刷新文件列表按鈕
flushLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
loadGroupFile();
}
//鼠標移入時
public void mouseEntered(MouseEvent e) { // 鼠標移動到這裏的事件
flushLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // 讓鼠標移動到
}
});
}
/** * 鏈接服務器 */
private void connectServer(){
//鏈接服務器
try {
//初始化
client_socket = new Socket(ip,port);
client_out = new PrintStream(client_socket.getOutputStream(),true);
client_in = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
//讀取文件列表
client_out.println("@action=loadFileList");
//開啓線程監聽服務器消息
new ClientThread().start();
} catch (IOException e) {
e.printStackTrace();
}
}
/** * 監聽服務器消息 */
class ClientThread extends Thread{
public void run() {
try {
String fromServer_data;
int flag = 0;
while((fromServer_data=client_in.readLine()) != null){
//讀取羣文件列表
if(flag++ == 0){
if (fromServer_data.startsWith("@action=GroupFileList")){
String[] fileList = ParseDataUtil.getFileList(fromServer_data);
for (String filename : fileList) {
addToFileList(filename);
}
}
continue;
}
if(fromServer_data.startsWith("@action=GroupFileList")){
//從新渲染頂部面板
renderTop();
//註冊監聽
registerListener();
//渲染文件面板
String[] fileList = ParseDataUtil.getFileList(fromServer_data);
for (String filename : fileList) {
addToFileList(filename);
}
}
//文件上傳
if (fromServer_data.startsWith("@action=Upload")){
String res = ParseDataUtil.getUploadResult(fromServer_data);
if("NO".equals(res)){
JOptionPane.showMessageDialog(null,"文件已存在!");
}else if ("YES".equals(res)){
//開始上傳
if(currentUpploadFile != null){
//開啓新線程傳輸文件
new HandelFileThread(1).start();
}
}else if ("上傳完成".equals(res)){
JOptionPane.showMessageDialog(null,res);
loadGroupFile();
}
}
//文件下載
if(fromServer_data.startsWith("@action=Download")){
String res = ParseDataUtil.getDownResult(fromServer_data);
if(res.equals("文件不存在")){
JOptionPane.showMessageDialog(null,"該文件不存在404");
}else {
String downFileName = ParseDataUtil.getDownFileName(fromServer_data);
String downFileSize = ParseDataUtil.getDownFileSize(fromServer_data);
//開啓新線程傳輸文件
new HandelFileThread(0,downFileName,downFileSize).start();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**---------------------------------------------------------------------------------- * 文件傳輸線程 */
class HandelFileThread extends Thread{
private int mode; //文件傳輸模式 1-上傳 2-下載
private String filename;
private Long fileSize;
public HandelFileThread(int mode) {
this.mode = mode;
}
public HandelFileThread(int mode,String filename,String fileSize){
this.mode = mode;
this.filename = filename;
this.fileSize = Long.parseLong(fileSize);
}
public void run() {
try {
//上傳文件模式
if(this.mode == 1){
Socket socket = new Socket(ip,8888);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(currentUpploadFile));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
int len;
int i = 0;
double sum = 0;
byte[] arr = new byte[8192];
String schedule;
System.out.println("開始上傳--文件大小爲:"+currentUpploadFile.length());
while((len = bis.read(arr)) != -1){
bos.write(arr,0,len);
bos.flush();
sum += len;
if (i++ %100 == 0){
schedule = "上傳進度:"+100*sum/currentUpploadFile.length()+"%";
System.out.println(schedule);
}
}
//上傳完成
socket.shutdownOutput();
System.out.println("上傳進度:100%");
}
//下載文件模式
if(this.mode == 0){
Socket socket = new Socket(ip,8888);
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(downloadSavePath+"/"+filename));
int len;
byte[] arr =new byte[8192];
double sumDown = 0;
int i = 0;
System.out.println("客戶端開始下載 ");
while ((len = bis.read(arr)) != -1){
sumDown += len;
if(i++%100 == 0)
System.out.println("下載進度爲:"+100*sumDown/fileSize+"%");
bos.write(arr,0,len);
bos.flush();
}
bos.close();
bis.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//啓動程序
public static void main(String[] args) throws Exception {
new GroupFileView();
}
複製代碼
public class ParseDataUtil {
/** * * 下載文件消息格式: @action=Download["fileName":"fileSize":"result"] * 參數說明: * fileName 要下載的文件的名字 * fileSize 要下載的文件的大小 result 下載許可 */
public static String getDownFileName(String data){
return data.substring(data.indexOf("[")+1,data.indexOf(":"));
}
public static String getDownFileSize(String data){
return data.substring(data.indexOf(":")+1,data.lastIndexOf(":"));
}
public static String getDownResult(String data){
return data.substring(data.lastIndexOf(":")+1,data.length()-1);
}
/** * * 上傳文件消息格式: @action=Upload["fileName":"fileSize":result] 參數說明: * fileName 要上傳的文件的名字 * fileSize 要上傳的文件的大小 result 上傳許可 */
public static String getUploadFileName(String data){
return data.substring(data.indexOf("[")+1,data.indexOf(":"));
}
public static String getUploadFileSize(String data){
return data.substring(data.indexOf(":")+1,data.lastIndexOf(":"));
}
public static String getUploadResult(String data){
return data.substring(data.lastIndexOf(":")+1,data.length()-1);
}
/** 返回文件列表格式 @action=GroupFileList["fileName":"fileName":"fileName"...] */
public static String[] getFileList(String data){
String list = data.substring(data.indexOf("[")+1,data.length()-1);
return list.split(":");
}
}
複製代碼