服务器端代码:
1。服务器端的图形化类
package service;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
@SuppressWarnings("serial")
public class Main extends JFrame {
private Main main;
private JButton start;
private JButton stop;
private JTextField port;
private JTextArea result;
public Main(){
this.setLayout(new BorderLayout());
//top
JPanel topPanel = new JPanel();
JLabel lable1 = new JLabel("Port");
this.port = new JTextField();
port.setColumns(10);
port.setText("45678");
this.start = new JButton("Listen");
start.setName("Listen");
this.stop = new JButton("Stop");
stop.setName("Stop");
stop.setEnabled(false);
topPanel.add(lable1);
topPanel.add(port);
topPanel.add(start);
topPanel.add(stop);
//center
JPanel centerPanel = new JPanel();
this.result = new JTextArea(15,50);
this.result.setLineWrap(true);
this.result.setFont(new Font("仿宋",Font.BOLD,12));
JScrollPane jsp = new JScrollPane(this.result);
this.result.setAutoscrolls(true);
this.result.setEnabled(false);
centerPanel.add(jsp);
this.add(centerPanel,BorderLayout.CENTER);
this.add(topPanel,BorderLayout.NORTH);
this.setTitle("Service");
this.setResizable(false);
this.setSize(600, 350);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = (int) dimension.getWidth();
int screenHeight = (int) dimension.getHeight();
this.setLocation((screenWidth - this.getWidth())/2, (screenHeight - this.getHeight())/2);
this.setVisible(true);
this.addWindowListener(new MyWindowAdapter());
start.addMouseListener(new MyMouseAdapter());
stop.addMouseListener(new MyMouseAdapter());
this.main = this;
}
public void printMessage(String message){
//System.out.println(message);
this.result.append(message + "\n");
}
public static void main(String[] args) {
new Main();
}
/**
* 开始监听,停止监听
*/
class MyMouseAdapter extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
if(e.getSource() instanceof JButton){
JButton button = (JButton) e.getSource();
if(button == start && button.isEnabled()){
stop.setEnabled(true);
start.setEnabled(false);
main.printMessage("服务器启动中...");
Service.instance(Integer.valueOf(port.getText()), main);
}else if(button == stop && button.isEnabled()){
start.setEnabled(true);
stop.setEnabled(false);
main.printMessage("服务器关闭中...");
Service.close();
}
}
}
}
/**
* 控制窗体关闭
*/
class MyWindowAdapter extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
Service.close();
System.exit(0);
super.windowClosing(e);
}
}
}
2.服务器端的,Socket类
package service;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.List;
public class Service{
private static Service service;
private static int port;
private static Main main;
private static AcceptClient ac;
private Service(){
ac = new AcceptClient();
ac.start();
}
/**
* 单例
*/
public static Service instance(int port,Main main){
Service.port = port;
Service.main = main;
if(service == null){
service = new Service();
}
return service;
}
public static void close(){
ac.stopThread();
Service.service = null;
}
class AcceptClient extends Thread{
private boolean isRun = true;
public void stopThread(){
this.isRun = false;
}
@Override
public void run() {
Socket socket = null;
try {
ServerSocket serviceSocket = new ServerSocket();
SocketAddress address = new InetSocketAddress(port);
serviceSocket.bind(address);
while(true && isRun){
socket = serviceSocket.accept();
main.printMessage("监听到客户端:" + socket.getInetAddress().getHostAddress());
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//ObjectInputStream ois = new ObjectInputStream(bis);
DataInputStream dis = new DataInputStream(bis);
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
//ObjectOutputStream oos = new ObjectOutputStream(bos);
DataOutputStream dos = new DataOutputStream(bos);
String clientVersion = dis.readUTF();//1.readUTF
Service.main.printMessage("客户端:" + socket.getInetAddress().getHostAddress()
+ " 的版本是 " + clientVersion);
ServiceFile sf = new ServiceFile();
dos.writeUTF(sf.getServiceVersion());//writeInt
if(sf.isNeedUpdate(clientVersion)){
dos.writeUTF("Yes");//2.wrietUTF
dos.flush();
List<String> files = sf.getUpdateFiles();
dos.writeInt(files.size());//2.wrietUTF
dos.flush();
for(int i = 0 ; i < files.size() ; i ++){
String filePath = files.get(i);
filePath = new String(filePath.getBytes("UTF-8"));
dos.writeUTF(filePath);//3.writeUTF
dos.flush();
}
List<Long> fileSizes = sf.getUpdateFilesSize();
for(int i = 0 ; i < files.size() ; i ++){
Long fileSize = fileSizes.get(i);
dos.writeLong(fileSize);//3.writeLong
dos.flush();
}
for(int i = 0 ; i < files.size() ; i ++){
String filePath = files.get(i);
filePath = new String(filePath.getBytes("UTF-8"));
FileInputStream fis = sf.getFileInputStream(filePath);
//DataInputStream dfis = new DataInputStream(fis);
int length = 0;
byte[] b = new byte[102400];
while((length = fis.read(b)) != -1){
dos.write(b,0,length);//4.write
//dos.flush();
}
fis.close();
dos.flush();
}
}else{
dos.writeUTF("No");//2.wrietUTF
dos.flush();
}
socket.close();
}
serviceSocket.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3。 服务器端的后台文件操作类
package service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class ServiceFile {
private String version;//服务器版本号
/**
* 查找服务器上最新版本
*/
public String getServiceVersion(){
Properties p = new Properties();
try {
p.load(new FileInputStream("./service_version/version.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.version = p.getProperty("version");
return this.version;
}
/**
* 判断是否需要更新文件
*/
public boolean isNeedUpdate(String oldVersion){
String[] newVersions = getServiceVersion().split("\\.");
String[] oldVersions = oldVersion.split("\\.");
for(int i = 0; i < newVersions.length; i ++){
int n = 0;
int o = 0;
if(newVersions[i] != null){
n = Integer.valueOf(newVersions[i]);
}
if(oldVersions[i] != null){
o = Integer.valueOf(oldVersions[i]);
}
if(n > o){
return true;
}
}
return false;
}
public List<String> getUpdateFiles(){
if(this.version == null){
this.version = this.getServiceVersion();
}
String baseDir = "./service_version/" + this.version + "/";
return this.listFiles(baseDir);
}
private List<String> listFiles(String path){
List<String> filePaths = new ArrayList<String>();
File baseFile = new File(path);
if(baseFile.isFile()){
filePaths.add(this.filterFilePth(baseFile.getPath()));
}else{
File[] files = baseFile.listFiles();
for(int i = 0 ; i < files.length ; i ++){
List<String> tempFilePath = this.listFiles(files[i].getPath());
filePaths.addAll(tempFilePath);
}
}
return filePaths;
}
public List<Long> getUpdateFilesSize(){
List<Long> filesSizes = new ArrayList<Long>();
List<String> filePaths = this.getUpdateFiles();
String baseDir = "./service_version/" + this.version + "/";
for(int i = 0; i < filePaths.size(); i ++){
File file = new File(baseDir + filePaths.get(i));
filesSizes.add(file.length());
}
return filesSizes;
}
private String filterFilePth(String path){
int position = path.indexOf(this.version);
path = path.substring(position + this.version.length() + 1);
return path;
}
public FileInputStream getFileInputStream(String filePath){
if(this.version == null){
this.version = this.getServiceVersion();
}
FileInputStream fis = null;
try {
fis = new FileInputStream("./service_version/" + this.version + "/" + filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return fis;
}
public static void main(String[] args) {
ServiceFile sf = new ServiceFile();
List<String> paths = sf.getUpdateFiles();
for(int i = 0; i < paths.size(); i ++){
System.out.println(paths.get(i));
}
}
}
客户端代码 与服务的同样的架构层
1.前端的图形界面类
package client;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
@SuppressWarnings("serial")
public class Main extends JFrame {
private Main main;
private JButton update;
private JTextField address;
private JTextField port;
private JTextArea result;
private JScrollPane jsp;
private JProgressBar jpb;
public Main(){
this.setLayout(new BorderLayout());
//top
JPanel topPanel = new JPanel();
JLabel lable1 = new JLabel("IP");
JLabel lable2 = new JLabel("Port");
this.address = new JTextField();
address.setColumns(20);
address.setText("127.0.0.1");
this.port = new JTextField();
port.setColumns(10);
port.setText("45678");
this.update = new JButton("Update");
update.setName("Update");
topPanel.add(lable1);
topPanel.add(address);
topPanel.add(lable2);
topPanel.add(port);
topPanel.add(update);
//center
JPanel centerPanel = new JPanel();
this.result = new JTextArea(15,50);
this.result.setLineWrap(true);
this.result.setFont(new Font("仿宋",Font.BOLD,12));
this.jsp = new JScrollPane(this.result);
this.result.setAutoscrolls(true);
this.result.setEnabled(false);
centerPanel.add(jsp);
//botton
this.jpb = new JProgressBar(0,Integer.MAX_VALUE);
this.jpb.setSize(600, 50);
this.jpb.setVisible(false);
this.jpb.setStringPainted(true);
JPanel bottonPanel = new JPanel();
bottonPanel.add(this.jpb);
this.getContentPane().add(topPanel,BorderLayout.NORTH);
this.getContentPane().add(bottonPanel,BorderLayout.SOUTH);
this.getContentPane().add(centerPanel,BorderLayout.CENTER);
this.setTitle("Client");
this.setResizable(false);
this.setSize(600, 350);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = (int) dimension.getWidth();
int screenHeight = (int) dimension.getHeight();
this.setLocation((screenWidth - this.getWidth())/2, (screenHeight - this.getHeight())/2);
this.setVisible(true);
this.addWindowListener(new MyWindowAdapter());
update.addMouseListener(new MyMouseAdapter());
this.main = this;
}
public void printMessage(String message){
//System.out.println(message);
this.result.append(message + "\n");
this.result.selectAll();
}
public void setEnableUpdateButton(){
this.update.setEnabled(true);
}
public void initProcessBar(Long max){
int temMax = (int)(max/1024/1024);
this.jpb.setVisible(true);
this.jpb.setMinimum(1);
this.jpb.setMaximum(temMax);
this.jpb.updateUI();
}
public void setProcessBarValue(Long value){
int temValue = (int)(value/1024/1024);
this.jpb.setString("当前进度:" + ((temValue * 100)/this.jpb.getMaximum()) + "%");
this.jpb.setValue(temValue);
}
public static void main(String[] args) {
new Main();
}
/**
* 开始监听,停止监听
*/
class MyMouseAdapter extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
if(e.getSource() instanceof JButton){
JButton button = (JButton) e.getSource();
if(button == update && button.isEnabled()){
update.setEnabled(false);
String ip = address.getText();
int p = Integer.valueOf(port.getText());
new Client(ip, p, main);
}
}
}
}
/**
* 控制窗体关闭
*/
class MyWindowAdapter extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
super.windowClosing(e);
}
}
}
2。 客户端的Socket操作类
package client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
public class Client extends Thread{
private String ip;
private int port;
private Main main;
public Client(String ip ,int port, Main main){
this.ip = ip;
this.port = port;
this.main = main;
new Thread(this).start();
}
@Override
public void run() {
try {
//InetAddress inetAddress = InetAddress.getByName(ip);
SocketAddress address = new InetSocketAddress(ip,port);
Socket socket = new Socket();
socket.connect(address);
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//ObjectInputStream ois = new ObjectInputStream(bis);
DataInputStream dis = new DataInputStream(bis);
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
//ObjectOutputStream oos = new ObjectOutputStream(bos);
DataOutputStream dos = new DataOutputStream(bos);
ClientFile cf = new ClientFile();
String clientVersion = cf.getClientVersion();
this.main.printMessage("客户端的版本是 " + clientVersion);
dos.writeUTF(clientVersion);//1.writeUTF
dos.flush();
String serviceVersion = dis.readUTF();//readUTF
this.main.printMessage("服务器最新版本为:" + serviceVersion);
String isNeedUpdate = dis.readUTF();//2.readUTF
int updateFileSize = 0;
if("Yes".equals(isNeedUpdate)){
updateFileSize = dis.readInt();
this.main.printMessage("总共有更新文件数量:" + updateFileSize);
List<String> filePaths = new ArrayList<String>();
List<Long> fileSizes = new ArrayList<Long>();
for(int i = 0; i < updateFileSize; i ++){
String filePath = dis.readUTF();//3.readUTF
filePaths.add(filePath);
}
Long maxSize = 0L;
for(int i = 0; i < updateFileSize; i ++){
Long fileSize = dis.readLong();//3.readLong
fileSizes.add(fileSize);
maxSize += fileSize;
}
this.main.initProcessBar(maxSize);
Long currentDownLoadSize = 0L;
for(int i = 0; i < updateFileSize; i ++){
File file = cf.isExistOrCreate(filePaths.get(i));
FileOutputStream fos = cf.getFileOutputStream(file);
int length = 0;
byte[] b = new byte[102400];
while((length + b.length) <= fileSizes.get(i)){
dis.read(b);
fos.write(b, 0, b.length);
length = length + b.length;
}
int leftLength = (int)(fileSizes.get(i) - length);
dis.read(b,0,leftLength);
fos.write(b,0,leftLength);
fos.close();
currentDownLoadSize += fileSizes.get(i);
this.main.setProcessBarValue(currentDownLoadSize);
this.main.printMessage(filePaths.get(i) + "..............." + fileSizes.get(i) + "B");
}
cf.setClientVersion(serviceVersion);
this.main.printMessage("已经升级为最新版本");
}else{
this.main.printMessage("客户端是最新版本,不需要升级");
}
this.main.setEnableUpdateButton();
dos.close();
dis.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3。本地文件的后台操作类
package client;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class ClientFile {
private String version;//客户端版本号
private String installDir;//安装路径
/**
* 查找客户端上最新版本
*/
public String getClientVersion(){
Properties p = new Properties();
try {
p.load(new FileInputStream("./client_version/version.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.version = p.getProperty("version");
return this.version;
}
public void setClientVersion(String version){
Properties p = new Properties();
try {
FileInputStream fis = new FileInputStream("./client_version/version.properties");
p.load(fis);
Enumeration<String> e = (Enumeration<String>) p.propertyNames();
while(e.hasMoreElements()){
String key = e.nextElement();
String value = p.getProperty(key);
p.put(key, value);
}
p.put("version", version);
FileOutputStream fos = new FileOutputStream("./client_version/version.properties");
p.store(fos, "update from service");
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getInstallDir(){
Properties p = new Properties();
try {
p.load(new FileInputStream("./client_version/version.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.installDir = p.getProperty("installDir");
return this.installDir;
}
public File isExistOrCreate(String filePath){
if(this.installDir == null){
this.installDir = this.getInstallDir();
}
File file = new File(this.installDir + filePath);
//System.out.println("path: " + this.installDir + filePath);
if(file.exists()){
return file;
}else{
int end = filePath.lastIndexOf("\\");
if(end != -1){
//System.out.println("parent Dir : " + file.getParent());
File folder = new File(file.getParent());
folder.mkdirs();
folder.setReadable(true);
folder.setWritable(true);
}
}
file = new File(this.installDir + filePath);
if(file.exists()){
return file;
}
try {
file.createNewFile();
file.setReadable(true);
file.setWritable(true);
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
public FileOutputStream getFileOutputStream(File file){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return fos;
}
}
目录结构,和运行截图
下载地址:可以去我的下载地址,我已经传我下载空间了!!