CS结构软件自动升级实现(三)
接 CS结构软件自动升级实现(二):
AUpdSrvProc.java服务端服务线程,关键代码之一:
ClientVerParser.java:
AutoUpdateClient.java客户端升级处理进程,关键代码之二:
看来源码还是有点多,只能再分一次了,否则电脑就快死机了,余下见(四)。
AUpdSrvProc.java服务端服务线程,关键代码之一:
1
/** */
/********************************************************************
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :AUpdSrvProc.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-22<p>
7 * 程序功能(类)描述 :<p>
8 * 自动更新服务端处理进程
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.io.StringReader;
21 import java.net.Socket;
22 import java.util.HashMap;
23
24 /** */ /**
25 * @author kfzx-luoc
26 *
27 * TODO To change the template for this generated type comment go to
28 * Window - Preferences - Java - Code Style - Code Templates
29 */
30 public class AUpdSrvProc extends Thread
31 {
32 private Socket socket = null;
33 private InputStream socketIn;
34 private OutputStream socketOut;
35 private Config config = Config.getInstance();//配置文件对像
36 private ClientVerParser cvPaser = null;
37 private HashMap cFiles = new HashMap();
38
39 byte bFlag [] = new byte[1];//标识位
40 byte bCmd[] = new byte[8];//命令
41
42 public AUpdSrvProc(Socket socket)
43 {
44 this.socket = socket;
45 }
46 /** *//**
47 * 接收客户端的升级请求,并进行处理
48 */
49 public void run()
50 {
51 try
52 {
53 config.refresh();//重新更新配置信息
54 socketIn = socket.getInputStream();
55 socketOut = socket.getOutputStream();
56 byte datahead [] = new byte[5];//数据头部,第一位用于标识是数据,后四位为长度
57 byte buffer[] = new byte[AUPD.BUFFER_SIZE];//存放数据头部和数据头部
58 byte data[] = new byte[AUPD.DATA_SIZE];//存放具体的数据内容
59 while(true)
60 {
61 //读取标志位
62 int len = socketIn.read(bFlag,0,1);
63 if(len!=1)
64 {
65 Config.print(socket.getInetAddress()+":读取标识位失败");
66 socketOut.write(Config.getCmd(AUPD.BYE));//结束
67 break;
68 }
69 if(bFlag[0]==AUPD.CMD_DATA_SECT)//命令行
70 {
71 len = socketIn.read(bCmd,0,8);
72 if(len!=8)
73 {
74 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+bCmd);
75 socketOut.write(Config.getCmd(AUPD.BYE));//结束
76 break;
77 }
78 if(Config.parseCmd(bCmd).equals(AUPD.READY_TO_UPDATE))//客户端已经准备好更新了
79 {
80 Config.print(socket.getInetAddress()+":客户端已经准备好接收更新文件");
81 int ret = sendUpdateFile();
82 switch(ret)
83 {
84 case 0:
85 socketOut.write(Config.getCmd(AUPD.UPDATED_FAILURE));//失败
86 break;
87 case 1:
88 socketOut.write(Config.getCmd(AUPD.UPDATED_SUCCESSFUL));//成功
89 break;
90 default:
91 socketOut.write(Config.getCmd(AUPD.NOTNEED_UPDATED));//无需更新
92 break;
93 }
94 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//结束链接
95 {
96 socketOut.write(Config.getCmd(AUPD.BYE));//结束
97 break;
98 }
99 }else if(bFlag[0]==AUPD.MARK_DATA_SECT || bFlag[0]==AUPD.MARK_DATA_END)//数据内容
100 {
101 if(Config.parseCmd(bCmd).equals(AUPD.SEND_CLIENT_VERSION))//进行版本信息接收处理
102 {
103 receiveClientVer(bFlag[0]);
104 }else
105 {
106 Config.print("出现非期望数据,"+new String(bCmd));
107 socketOut.write(Config.getCmd(AUPD.BYE));//结束
108 break;
109 }
110 }else
111 {
112 Config.print(socket.getInetAddress()+":非期望标识位,"+bFlag[0]);
113 socketOut.write(Config.getCmd(AUPD.BYE));//结束
114 break;
115 }
116 }//END while(ture)
117 //关闭资源
118 socketIn.close();
119 socketOut.close();
120 socket.close();
121 } catch (IOException e)
122 {
123 Config.print("处理客户端升级请求失败,"+socket.getInetAddress()+","+e);
124 e.printStackTrace();
125 }
126 }
127 /** *//**
128 * 方法名称:sendUpdateFile<p>
129 * 方法功能:<p>
130 * 参数说明:<p>
131 * 返回:int<p>
132 * 作者:kfzx-luoc
133 * 日期:2008-12-23
134 * @return 0.更新失败 1.更新成功 2.无需更新
135 */
136 private int sendUpdateFile()
137 {
138 try
139 {
140 //检查服务器和客户端版本号是否一致,如果一致辞,则无需升级
141 if (config.getVerstion().equals(cvPaser.getVerstion()))
142 {
143 Config.print(socket.getInetAddress()+":版本一致,无需更新");
144 return 2;
145 }
146 //开始进行处理
147 UpdFile srvFiles [] = config.getFiles();
148 boolean isSuccess = true;
149 for(int i=0;i<srvFiles.length;i++)
150 {
151 UpdFile cf = (UpdFile)cFiles.get(srvFiles[i].getName());
152 //文件不存在或版本号不一致则需要更新该文件
153 if(cf==null || !cf.getVersion().equals(srvFiles[i].getVersion()))
154 {
155 if(!sendFile(srvFiles[i]))
156 {
157 isSuccess = false;
158 }
159 }
160 }//END for
161 //发送版本信息文件,发送更新信息文件
162 if(isSuccess)
163 {
164 UpdFile verFile = new UpdFile("autoupdate.xml");
165 verFile.setPath("." + File.separator + "config");
166 verFile.setType(0);
167 verFile.setVersion(config.getVerstion());
168 if(!sendFile(verFile))
169 {
170 Config.print(socket.getInetAddress()+":发送版本文件失败");
171 return 0;
172 }
173 //发送更新信息
174 UpdFile infFile = new UpdFile("history.htm");
175 infFile.setPath("." + File.separator + "config");
176 infFile.setType(0);
177 infFile.setVersion(config.getVerstion());
178 if(!sendFile(infFile))
179 {
180 Config.print(socket.getInetAddress()+":发送最新信息失败");
181 }
182 return 1;
183 }else
184 {
185 return 0;
186 }
187 }catch(Exception e)
188 {
189 Config.print("处理需要更新文件失败,"+e);
190 e.printStackTrace();
191 return 0;
192 }
193 }
194 //0.失败 1.成功
195 private boolean sendFileAbsPath(String path)
196 {
197 try
198 {
199 byte buffer[] = new byte[AUPD.BUFFER_SIZE];
200 int len = 0;
201 //标识为数据段
202 buffer[0] = AUPD.MARK_DATA_SECT;
203 Config.copyArray(buffer, Config.getLen(path.getBytes().length), 1, 0, 4);//4位长度
204 //组合数据包
205 for (int i = 0; i < path.getBytes().length; i++)
206 buffer[i + 5] = path.getBytes()[i];
207 socketOut.write(buffer, 0, path.getBytes().length + 5);//前五位为头部1位标识+4位长度
208 //标识为数据段已结束,并发送至服务器
209 buffer[0] = AUPD.MARK_DATA_END;
210 socketOut.write(buffer, 0, 1);
211 socketOut.flush();
212 //检查客户端是否收到
213 len = socketIn.read(bFlag,0,1);
214 if(len!=1)
215 {
216 Config.print(socket.getInetAddress()+":读取标识位失败");
217 socketOut.write(Config.getCmd(AUPD.BYE));//结束
218 return false;
219 }
220 //读取命令
221 len = socketIn.read(bCmd,0,8);
222 if(len!=8)
223 {
224 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+bCmd);
225 socketOut.write(Config.getCmd(AUPD.BYE));//结束
226 return false;
227 }
228 if(Config.parseCmd(bCmd).equals(AUPD.RECEIVED_FILE_ABSOULT))//成功
229 {
230 Config.print(socket.getInetAddress()+":接收文件路径成功,"+path);
231 return true;
232 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//失败
233 {
234 Config.print(socket.getInetAddress()+":接收文件路径失败,"+path);
235 return false;
236 }else//异常
237 {
238 return false;
239 }
240 }catch(Exception e)
241 {
242 Config.print(socket.getInetAddress()+":发送文件路径失败,"+path);
243 e.printStackTrace();
244 return false;
245 }
246 }
247 //false.失败 true.成功
248 private boolean sendFile(UpdFile file)
249 {
250 try
251 {
252 File f = new File(Config.formatPath(file.getPath())+file.getName());
253 if(!f.exists()||!f.isFile())
254 {
255 Config.print(file+",不存在,无法更新");
256 return false;
257 }
258 Config.print(socket.getInetAddress()+":开始传输文件>>"+file);
259 socketOut.write(Config.getCmd(AUPD.SEND_FILE_ABSOULT));//发送文件全路径
260 String fileAbsPath = Config.formatPath(file.getPath())+file.getName();
261 if(!sendFileAbsPath(fileAbsPath))
262 {
263 return false;
264 }
265 socketOut.write(Config.getCmd(AUPD.START_TRANSMIT));//开始传输
266 FileInputStream fin = new FileInputStream(f);
267 //文件数据缓冲区
268 byte[] data = new byte[AUPD.DATA_SIZE];
269 // 发送数据缓冲区
270 byte[] buffer = new byte[AUPD.BUFFER_SIZE];
271 int len = -1;
272 while ((len=fin.read(data)) != -1)
273 {
274 // 标识为数据段
275 buffer[0] = AUPD.MARK_DATA_SECT;
276 Config.copyArray(buffer,Config.getLen(len),1,0,4);//存放长度
277 // 组合数据包
278 for (int i=0; i<len; i++)
279 buffer[i+5] = data[i];
280 socketOut.write(buffer,0,len+5);
281 }
282 // 标识为数据段已结束,并发送至服务器
283 buffer[0] = AUPD.MARK_DATA_END;
284 socketOut.write(buffer,0,1);
285 socketOut.flush();
286 fin.close();
287 //判断客户端是否收到
288 len = socketIn.read(bFlag,0,1);
289 if(len!=1)
290 {
291 Config.print(socket.getInetAddress()+":读取标识位失败");
292 socketOut.write(Config.getCmd(AUPD.BYE));//结束
293 return false;
294 }
295 //读取命令
296 len = socketIn.read(bCmd,0,8);
297 if(len!=8)
298 {
299 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+new String(bCmd));
300 socketOut.write(Config.getCmd(AUPD.BYE));//结束
301 return false;
302 }
303 if(Config.parseCmd(bCmd).equals(AUPD.TERMINATE_TRANSMIT))//成功
304 {
305 Config.print(socket.getInetAddress()+":传输文件'"+file+"'成功");
306 return true;
307 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//失败
308 {
309 Config.print(socket.getInetAddress()+":传输文件失败,"+file);
310 return false;
311 }else//异常
312 {
313 Config.print(socket.getInetAddress()+":传输文件异常,"+file+","+new String(bCmd));
314 return false;
315 }
316 }catch(Exception e)
317 {
318 Config.print("传输文件'"+file+"'失败,"+e);
319 e.printStackTrace();
320 return false;
321 }
322 }
323 private void receiveClientVer(byte flag)//第一位表示是数据内容还是结束内容
324 {
325 try
326 {
327 //接收数据缓冲区
328 byte flagb[] = new byte[1];//标志
329 byte lenb [] = new byte[4];//长度
330 //接收版本号信息
331 StringBuffer strBuf = new StringBuffer();//用于接收信息
332 int len = -1;
333 boolean isFirst = true;
334 boolean isOk = false;
335 flagb[0] = flag;
336 while(true)
337 {
338 //第一次
339 if(isFirst)
340 {
341 isFirst = false;
342 }else
343 {
344 len = socketIn.read(flagb,0,1);//读取标识位
345 if(len != 1)
346 {
347 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
348 break;
349 }
350 }
351 //读取数据长度
352 if(flagb[0]==AUPD.MARK_DATA_SECT)
353 {
354 len = socketIn.read(lenb, 0, 4);
355 if (len != 4)
356 {
357 Config.print(socket.getInetAddress() + ":读取数据头部失败");
358 break;
359 }
360 }
361 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
362 {
363 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
364 byte data[] = new byte[cLen];
365 len = socketIn.read(data, 0, cLen);
366 int totLen = len;
367 while (totLen < cLen)//不足位要重重读取
368 {
369 strBuf.append(new String(data, 0, len));
370 len = socketIn.read(data, 0, cLen - totLen);
371 totLen = totLen + len;
372 }
373 strBuf.append(new String(data, 0, len));
374 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
375 {
376 isOk = true;
377 break;
378 }else
379 {
380 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
381 break;
382 }
383 }//END while(true)
384 if(isOk)//成功
385 {
386 socketOut.write(Config.getCmd(AUPD.RECEIVED_CLIENT_VERSION));//临时测试
387 Config.print("接收客户端" + socket.getInetAddress() + " 版本信息成功");
388 cvPaser = new ClientVerParser(new StringReader(strBuf
389 .toString()));
390 UpdFile files[] = cvPaser.getFiles();
391 for (int i = 0; i < files.length; i++)
392 {
393 cFiles.put(files[i].getName(), files[i]);
394 }
395 }else//失败
396 {
397 socketOut.write(Config.getCmd(AUPD.BYE));//结束
398 }
399 }catch(Exception e)
400 {
401 Config.print("接收客户端"+socket.getInetAddress()+" 版本号信息处理失败,"+e);
402 }
403 }
404}
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :AUpdSrvProc.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-22<p>
7 * 程序功能(类)描述 :<p>
8 * 自动更新服务端处理进程
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.io.StringReader;
21 import java.net.Socket;
22 import java.util.HashMap;
23
24 /** */ /**
25 * @author kfzx-luoc
26 *
27 * TODO To change the template for this generated type comment go to
28 * Window - Preferences - Java - Code Style - Code Templates
29 */
30 public class AUpdSrvProc extends Thread
31 {
32 private Socket socket = null;
33 private InputStream socketIn;
34 private OutputStream socketOut;
35 private Config config = Config.getInstance();//配置文件对像
36 private ClientVerParser cvPaser = null;
37 private HashMap cFiles = new HashMap();
38
39 byte bFlag [] = new byte[1];//标识位
40 byte bCmd[] = new byte[8];//命令
41
42 public AUpdSrvProc(Socket socket)
43 {
44 this.socket = socket;
45 }
46 /** *//**
47 * 接收客户端的升级请求,并进行处理
48 */
49 public void run()
50 {
51 try
52 {
53 config.refresh();//重新更新配置信息
54 socketIn = socket.getInputStream();
55 socketOut = socket.getOutputStream();
56 byte datahead [] = new byte[5];//数据头部,第一位用于标识是数据,后四位为长度
57 byte buffer[] = new byte[AUPD.BUFFER_SIZE];//存放数据头部和数据头部
58 byte data[] = new byte[AUPD.DATA_SIZE];//存放具体的数据内容
59 while(true)
60 {
61 //读取标志位
62 int len = socketIn.read(bFlag,0,1);
63 if(len!=1)
64 {
65 Config.print(socket.getInetAddress()+":读取标识位失败");
66 socketOut.write(Config.getCmd(AUPD.BYE));//结束
67 break;
68 }
69 if(bFlag[0]==AUPD.CMD_DATA_SECT)//命令行
70 {
71 len = socketIn.read(bCmd,0,8);
72 if(len!=8)
73 {
74 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+bCmd);
75 socketOut.write(Config.getCmd(AUPD.BYE));//结束
76 break;
77 }
78 if(Config.parseCmd(bCmd).equals(AUPD.READY_TO_UPDATE))//客户端已经准备好更新了
79 {
80 Config.print(socket.getInetAddress()+":客户端已经准备好接收更新文件");
81 int ret = sendUpdateFile();
82 switch(ret)
83 {
84 case 0:
85 socketOut.write(Config.getCmd(AUPD.UPDATED_FAILURE));//失败
86 break;
87 case 1:
88 socketOut.write(Config.getCmd(AUPD.UPDATED_SUCCESSFUL));//成功
89 break;
90 default:
91 socketOut.write(Config.getCmd(AUPD.NOTNEED_UPDATED));//无需更新
92 break;
93 }
94 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//结束链接
95 {
96 socketOut.write(Config.getCmd(AUPD.BYE));//结束
97 break;
98 }
99 }else if(bFlag[0]==AUPD.MARK_DATA_SECT || bFlag[0]==AUPD.MARK_DATA_END)//数据内容
100 {
101 if(Config.parseCmd(bCmd).equals(AUPD.SEND_CLIENT_VERSION))//进行版本信息接收处理
102 {
103 receiveClientVer(bFlag[0]);
104 }else
105 {
106 Config.print("出现非期望数据,"+new String(bCmd));
107 socketOut.write(Config.getCmd(AUPD.BYE));//结束
108 break;
109 }
110 }else
111 {
112 Config.print(socket.getInetAddress()+":非期望标识位,"+bFlag[0]);
113 socketOut.write(Config.getCmd(AUPD.BYE));//结束
114 break;
115 }
116 }//END while(ture)
117 //关闭资源
118 socketIn.close();
119 socketOut.close();
120 socket.close();
121 } catch (IOException e)
122 {
123 Config.print("处理客户端升级请求失败,"+socket.getInetAddress()+","+e);
124 e.printStackTrace();
125 }
126 }
127 /** *//**
128 * 方法名称:sendUpdateFile<p>
129 * 方法功能:<p>
130 * 参数说明:<p>
131 * 返回:int<p>
132 * 作者:kfzx-luoc
133 * 日期:2008-12-23
134 * @return 0.更新失败 1.更新成功 2.无需更新
135 */
136 private int sendUpdateFile()
137 {
138 try
139 {
140 //检查服务器和客户端版本号是否一致,如果一致辞,则无需升级
141 if (config.getVerstion().equals(cvPaser.getVerstion()))
142 {
143 Config.print(socket.getInetAddress()+":版本一致,无需更新");
144 return 2;
145 }
146 //开始进行处理
147 UpdFile srvFiles [] = config.getFiles();
148 boolean isSuccess = true;
149 for(int i=0;i<srvFiles.length;i++)
150 {
151 UpdFile cf = (UpdFile)cFiles.get(srvFiles[i].getName());
152 //文件不存在或版本号不一致则需要更新该文件
153 if(cf==null || !cf.getVersion().equals(srvFiles[i].getVersion()))
154 {
155 if(!sendFile(srvFiles[i]))
156 {
157 isSuccess = false;
158 }
159 }
160 }//END for
161 //发送版本信息文件,发送更新信息文件
162 if(isSuccess)
163 {
164 UpdFile verFile = new UpdFile("autoupdate.xml");
165 verFile.setPath("." + File.separator + "config");
166 verFile.setType(0);
167 verFile.setVersion(config.getVerstion());
168 if(!sendFile(verFile))
169 {
170 Config.print(socket.getInetAddress()+":发送版本文件失败");
171 return 0;
172 }
173 //发送更新信息
174 UpdFile infFile = new UpdFile("history.htm");
175 infFile.setPath("." + File.separator + "config");
176 infFile.setType(0);
177 infFile.setVersion(config.getVerstion());
178 if(!sendFile(infFile))
179 {
180 Config.print(socket.getInetAddress()+":发送最新信息失败");
181 }
182 return 1;
183 }else
184 {
185 return 0;
186 }
187 }catch(Exception e)
188 {
189 Config.print("处理需要更新文件失败,"+e);
190 e.printStackTrace();
191 return 0;
192 }
193 }
194 //0.失败 1.成功
195 private boolean sendFileAbsPath(String path)
196 {
197 try
198 {
199 byte buffer[] = new byte[AUPD.BUFFER_SIZE];
200 int len = 0;
201 //标识为数据段
202 buffer[0] = AUPD.MARK_DATA_SECT;
203 Config.copyArray(buffer, Config.getLen(path.getBytes().length), 1, 0, 4);//4位长度
204 //组合数据包
205 for (int i = 0; i < path.getBytes().length; i++)
206 buffer[i + 5] = path.getBytes()[i];
207 socketOut.write(buffer, 0, path.getBytes().length + 5);//前五位为头部1位标识+4位长度
208 //标识为数据段已结束,并发送至服务器
209 buffer[0] = AUPD.MARK_DATA_END;
210 socketOut.write(buffer, 0, 1);
211 socketOut.flush();
212 //检查客户端是否收到
213 len = socketIn.read(bFlag,0,1);
214 if(len!=1)
215 {
216 Config.print(socket.getInetAddress()+":读取标识位失败");
217 socketOut.write(Config.getCmd(AUPD.BYE));//结束
218 return false;
219 }
220 //读取命令
221 len = socketIn.read(bCmd,0,8);
222 if(len!=8)
223 {
224 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+bCmd);
225 socketOut.write(Config.getCmd(AUPD.BYE));//结束
226 return false;
227 }
228 if(Config.parseCmd(bCmd).equals(AUPD.RECEIVED_FILE_ABSOULT))//成功
229 {
230 Config.print(socket.getInetAddress()+":接收文件路径成功,"+path);
231 return true;
232 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//失败
233 {
234 Config.print(socket.getInetAddress()+":接收文件路径失败,"+path);
235 return false;
236 }else//异常
237 {
238 return false;
239 }
240 }catch(Exception e)
241 {
242 Config.print(socket.getInetAddress()+":发送文件路径失败,"+path);
243 e.printStackTrace();
244 return false;
245 }
246 }
247 //false.失败 true.成功
248 private boolean sendFile(UpdFile file)
249 {
250 try
251 {
252 File f = new File(Config.formatPath(file.getPath())+file.getName());
253 if(!f.exists()||!f.isFile())
254 {
255 Config.print(file+",不存在,无法更新");
256 return false;
257 }
258 Config.print(socket.getInetAddress()+":开始传输文件>>"+file);
259 socketOut.write(Config.getCmd(AUPD.SEND_FILE_ABSOULT));//发送文件全路径
260 String fileAbsPath = Config.formatPath(file.getPath())+file.getName();
261 if(!sendFileAbsPath(fileAbsPath))
262 {
263 return false;
264 }
265 socketOut.write(Config.getCmd(AUPD.START_TRANSMIT));//开始传输
266 FileInputStream fin = new FileInputStream(f);
267 //文件数据缓冲区
268 byte[] data = new byte[AUPD.DATA_SIZE];
269 // 发送数据缓冲区
270 byte[] buffer = new byte[AUPD.BUFFER_SIZE];
271 int len = -1;
272 while ((len=fin.read(data)) != -1)
273 {
274 // 标识为数据段
275 buffer[0] = AUPD.MARK_DATA_SECT;
276 Config.copyArray(buffer,Config.getLen(len),1,0,4);//存放长度
277 // 组合数据包
278 for (int i=0; i<len; i++)
279 buffer[i+5] = data[i];
280 socketOut.write(buffer,0,len+5);
281 }
282 // 标识为数据段已结束,并发送至服务器
283 buffer[0] = AUPD.MARK_DATA_END;
284 socketOut.write(buffer,0,1);
285 socketOut.flush();
286 fin.close();
287 //判断客户端是否收到
288 len = socketIn.read(bFlag,0,1);
289 if(len!=1)
290 {
291 Config.print(socket.getInetAddress()+":读取标识位失败");
292 socketOut.write(Config.getCmd(AUPD.BYE));//结束
293 return false;
294 }
295 //读取命令
296 len = socketIn.read(bCmd,0,8);
297 if(len!=8)
298 {
299 Config.print(socket.getInetAddress()+":读取命令失败,CMD="+new String(bCmd));
300 socketOut.write(Config.getCmd(AUPD.BYE));//结束
301 return false;
302 }
303 if(Config.parseCmd(bCmd).equals(AUPD.TERMINATE_TRANSMIT))//成功
304 {
305 Config.print(socket.getInetAddress()+":传输文件'"+file+"'成功");
306 return true;
307 }else if(Config.parseCmd(bCmd).equals(AUPD.BYE))//失败
308 {
309 Config.print(socket.getInetAddress()+":传输文件失败,"+file);
310 return false;
311 }else//异常
312 {
313 Config.print(socket.getInetAddress()+":传输文件异常,"+file+","+new String(bCmd));
314 return false;
315 }
316 }catch(Exception e)
317 {
318 Config.print("传输文件'"+file+"'失败,"+e);
319 e.printStackTrace();
320 return false;
321 }
322 }
323 private void receiveClientVer(byte flag)//第一位表示是数据内容还是结束内容
324 {
325 try
326 {
327 //接收数据缓冲区
328 byte flagb[] = new byte[1];//标志
329 byte lenb [] = new byte[4];//长度
330 //接收版本号信息
331 StringBuffer strBuf = new StringBuffer();//用于接收信息
332 int len = -1;
333 boolean isFirst = true;
334 boolean isOk = false;
335 flagb[0] = flag;
336 while(true)
337 {
338 //第一次
339 if(isFirst)
340 {
341 isFirst = false;
342 }else
343 {
344 len = socketIn.read(flagb,0,1);//读取标识位
345 if(len != 1)
346 {
347 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
348 break;
349 }
350 }
351 //读取数据长度
352 if(flagb[0]==AUPD.MARK_DATA_SECT)
353 {
354 len = socketIn.read(lenb, 0, 4);
355 if (len != 4)
356 {
357 Config.print(socket.getInetAddress() + ":读取数据头部失败");
358 break;
359 }
360 }
361 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
362 {
363 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
364 byte data[] = new byte[cLen];
365 len = socketIn.read(data, 0, cLen);
366 int totLen = len;
367 while (totLen < cLen)//不足位要重重读取
368 {
369 strBuf.append(new String(data, 0, len));
370 len = socketIn.read(data, 0, cLen - totLen);
371 totLen = totLen + len;
372 }
373 strBuf.append(new String(data, 0, len));
374 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
375 {
376 isOk = true;
377 break;
378 }else
379 {
380 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
381 break;
382 }
383 }//END while(true)
384 if(isOk)//成功
385 {
386 socketOut.write(Config.getCmd(AUPD.RECEIVED_CLIENT_VERSION));//临时测试
387 Config.print("接收客户端" + socket.getInetAddress() + " 版本信息成功");
388 cvPaser = new ClientVerParser(new StringReader(strBuf
389 .toString()));
390 UpdFile files[] = cvPaser.getFiles();
391 for (int i = 0; i < files.length; i++)
392 {
393 cFiles.put(files[i].getName(), files[i]);
394 }
395 }else//失败
396 {
397 socketOut.write(Config.getCmd(AUPD.BYE));//结束
398 }
399 }catch(Exception e)
400 {
401 Config.print("接收客户端"+socket.getInetAddress()+" 版本号信息处理失败,"+e);
402 }
403 }
404}
ClientVerParser.java:
1
/** */
/********************************************************************
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :ClientVerParser.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-23<p>
7 * 程序功能(类)描述 :<p>
8 * 客户端版本号解释器
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.Reader;
16 import java.util.List;
17
18 import org.dom4j.Document;
19 import org.dom4j.Element;
20 import org.dom4j.io.SAXReader;
21
22 /** */ /**
23 * @author kfzx-luoc
24 *
25 * TODO To change the template for this generated type comment go to
26 * Window - Preferences - Java - Code Style - Code Templates
27 */
28 public class ClientVerParser
29 {
30 private Reader xml = null;
31 /** *//** xml的document*/
32 private Document doc = null;
33
34 public ClientVerParser(Reader reader)
35 {
36 xml = reader;
37 parse();
38 }
39
40 private void parse()
41 {
42 try
43 {
44 SAXReader reader = new SAXReader();
45 doc = reader.read(xml);
46 }catch(Exception e)
47 {
48 e.printStackTrace();
49 }
50 }
51 public String getVerstion()
52 {
53 List lst = doc.selectNodes("Info/Version");
54 Element el = (Element)lst.get(0);
55 return el.getText();
56 }
57 public UpdFile [] getFiles()
58 {
59 List file = doc.selectNodes("Info/Files");
60 List lst = ((Element)file.get(0)).elements();
61 if(lst.size()==0)
62 {
63 return null;
64 }
65 UpdFile files[] = new UpdFile[lst.size()];
66 for(int i=0;i<lst.size();i++)
67 {
68 Element el = (Element)lst.get(i);
69 List childs = el.elements();
70 Element name = (Element)childs.get(0);//Name
71 Element path = (Element)childs.get(1);//Path
72 Element ver = (Element)childs.get(2);//Version
73 files[i] = new UpdFile(name.getText());
74 if("File".equals(el.getName()))
75 {
76 files[i].setType(0);//文件
77 }else
78 {
79 files[i].setType(1);//目录
80 }
81 files[i].setPath(path.getText());
82 files[i].setVersion(ver.getText());
83 }
84 return files;
85 }
86 public String getServerPort()
87 {
88 List lst = doc.selectNodes("Info/UpdateServer/Port");
89 Element el = (Element)lst.get(0);
90 return el.getText();
91 }
92}
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :ClientVerParser.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-23<p>
7 * 程序功能(类)描述 :<p>
8 * 客户端版本号解释器
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.Reader;
16 import java.util.List;
17
18 import org.dom4j.Document;
19 import org.dom4j.Element;
20 import org.dom4j.io.SAXReader;
21
22 /** */ /**
23 * @author kfzx-luoc
24 *
25 * TODO To change the template for this generated type comment go to
26 * Window - Preferences - Java - Code Style - Code Templates
27 */
28 public class ClientVerParser
29 {
30 private Reader xml = null;
31 /** *//** xml的document*/
32 private Document doc = null;
33
34 public ClientVerParser(Reader reader)
35 {
36 xml = reader;
37 parse();
38 }
39
40 private void parse()
41 {
42 try
43 {
44 SAXReader reader = new SAXReader();
45 doc = reader.read(xml);
46 }catch(Exception e)
47 {
48 e.printStackTrace();
49 }
50 }
51 public String getVerstion()
52 {
53 List lst = doc.selectNodes("Info/Version");
54 Element el = (Element)lst.get(0);
55 return el.getText();
56 }
57 public UpdFile [] getFiles()
58 {
59 List file = doc.selectNodes("Info/Files");
60 List lst = ((Element)file.get(0)).elements();
61 if(lst.size()==0)
62 {
63 return null;
64 }
65 UpdFile files[] = new UpdFile[lst.size()];
66 for(int i=0;i<lst.size();i++)
67 {
68 Element el = (Element)lst.get(i);
69 List childs = el.elements();
70 Element name = (Element)childs.get(0);//Name
71 Element path = (Element)childs.get(1);//Path
72 Element ver = (Element)childs.get(2);//Version
73 files[i] = new UpdFile(name.getText());
74 if("File".equals(el.getName()))
75 {
76 files[i].setType(0);//文件
77 }else
78 {
79 files[i].setType(1);//目录
80 }
81 files[i].setPath(path.getText());
82 files[i].setVersion(ver.getText());
83 }
84 return files;
85 }
86 public String getServerPort()
87 {
88 List lst = doc.selectNodes("Info/UpdateServer/Port");
89 Element el = (Element)lst.get(0);
90 return el.getText();
91 }
92}
AutoUpdateClient.java客户端升级处理进程,关键代码之二:
1
/** */
/********************************************************************
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :AutoUpdateClient.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-23<p>
7 * 程序功能(类)描述 :<p>
8 * 自动升级客户端对像
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.FileOutputStream;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.net.Socket;
21
22 /** */ /**
23 * @author kfzx-luoc
24 *
25 * TODO To change the template for this generated type comment go to
26 * Window - Preferences - Java - Code Style - Code Templates
27 */
28 public class AutoUpdateClient
29 {
30 private Socket socket = null;
31 private OutputStream socketOut;
32 private InputStream socketIn;
33 private Config config = Config.getInstance();//配置文件对像
34 private String currFileAbs = "";//当前更新文件的全路径
35 public AutoUpdateClient()
36 {
37 try
38 {
39 socket = new Socket(config.getServerIp(),Integer.parseInt(config.getServerPort()));
40 socket.setSoTimeout(30000);//30秒
41 }catch(Exception e)
42 {
43 Config.print("创建与自动升级服务器之间的连接失败,"+e);
44 e.printStackTrace();
45 }
46 }
47 public void update()
48 {
49 if(socket == null)
50 {
51 Config.print("无法与服务器连接,升级失败");
52 return;
53 }
54 try
55 {
56 socketOut = socket.getOutputStream();
57 socketIn = socket.getInputStream();
58
59 //开始升级处理
60 byte flag [] = new byte[1];
61 byte cmd[] = new byte[8];//命令
62 byte datahead [] = new byte[5];//数据头部,第一位用于标识是数据,后四位为长度
63 byte buffer[] = new byte[AUPD.BUFFER_SIZE];//存放数据头部和数据头部
64 byte data[] = new byte[AUPD.DATA_SIZE];//存放具体的数据内容
65 //发送本地版本信息给服务器
66 socketOut.write(Config.getCmd(AUPD.SEND_CLIENT_VERSION));//发送传输版本信息命令
67 sendClientVer();//发送版本信息
68 while(true)
69 {
70 //读取信息
71 int len = socketIn.read(flag,0,1);
72 if(len!=1)
73 {
74 Config.print("读取标识位失败");
75 socketOut.write(Config.getCmd(AUPD.BYE));//结束
76 break;
77 }
78 if(flag[0]==AUPD.CMD_DATA_SECT)//命令行
79 {
80 len = socketIn.read(cmd,0,8);
81 if(len!=8)
82 {
83 Config.print("读取命令失败");
84 socketOut.write(Config.getCmd(AUPD.BYE));//结束
85 break;
86 }
87 if(Config.parseCmd(cmd).equals(AUPD.RECEIVED_CLIENT_VERSION))//收到版本信息
88 {
89 Config.print("服务器成功收到版本信息");
90 socketOut.write(Config.getCmd(AUPD.READY_TO_UPDATE));
91 continue;
92 }else if(Config.parseCmd(cmd).equals(AUPD.SEND_FILE_ABSOULT))//接收文件全路径
93 {
94 Config.print("开始接收文件路径名");
95 }else if(Config.parseCmd(cmd).equals(AUPD.UPDATED_FAILURE))//更新失败
96 {
97 Config.print("版本更新失败");
98 socketOut.write(Config.getCmd(AUPD.BYE));//结束
99 break;
100 }else if(Config.parseCmd(cmd).equals(AUPD.UPDATED_SUCCESSFUL))//更新成功
101 {
102 Config.print("版本更新成功");
103 socketOut.write(Config.getCmd(AUPD.BYE));//结束
104 //打开最新信息
105 openFile(".\\config\\history.htm");
106 break;
107 }else if(Config.parseCmd(cmd).equals(AUPD.NOTNEED_UPDATED))//无需更新
108 {
109 Config.print("已经是最新版本,无需更新");
110 socketOut.write(Config.getCmd(AUPD.BYE));//结束
111 break;
112 }else if(Config.parseCmd(cmd).equals(AUPD.BYE))//结束链接
113 {
114 socketOut.write(Config.getCmd(AUPD.BYE));//结束
115 break;
116 }
117 }else if(flag[0]==AUPD.MARK_DATA_SECT || flag[0]==AUPD.MARK_DATA_END)//数据内容
118 {
119 if(Config.parseCmd(cmd).equals(AUPD.SEND_FILE_ABSOULT))//接收文件全路径
120 {
121 currFileAbs = receiveFileAbsPath(flag[0]);
122 if(currFileAbs!=null && !currFileAbs.equals(""))//成功
123 {
124 socketOut.write(Config.getCmd(AUPD.RECEIVED_FILE_ABSOULT));
125 Config.print("接收文件全路径‘"+currFileAbs+"’成功");
126 }else
127 {
128 Config.print("接收文件全路径失败");
129 socketOut.write(Config.getCmd(AUPD.BYE));//结束
130 break;
131 }
132 }else if(Config.parseCmd(cmd).equals(AUPD.START_TRANSMIT))//接收文件
133 {
134 if(receiveFile(flag[0]))
135 {
136 socketOut.write(Config.getCmd(AUPD.TERMINATE_TRANSMIT));
137 }else
138 {
139 socketOut.write(Config.getCmd(AUPD.BYE));
140 }
141 }else
142 {
143 Config.print("出现非期望数据,"+new String(cmd));
144 socketOut.write(Config.getCmd(AUPD.BYE));//结束
145 break;
146 }
147 }else
148 {
149 Config.print("非期望标识位,"+flag[0]);
150 socketOut.write(Config.getCmd(AUPD.BYE));//结束
151 break;
152 }
153 }//END while(true)
154
155 //关闭资源及链接
156 socketOut.close();
157 socketIn.close();
158 socket.close();
159 Config.print("自动升级处理完毕");
160 }catch(Exception e)
161 {
162 Config.print("升级处理失败,"+e);
163 e.printStackTrace();
164 }
165 }
166 private void openFile(String file)
167 {
168 try
169 {
170 Runtime.getRuntime().exec("cmd /c "+file);
171 }catch(Exception e)
172 {
173 e.printStackTrace();
174 }
175 }
176 private String receiveFileAbsPath(byte flag)
177 {
178 String absPath = "";
179 //接收文件全路径
180 try
181 {
182 //接收数据缓冲区
183 byte flagb[] = new byte[1];//标志
184 byte lenb [] = new byte[4];//长度
185 //接收文件全路径
186 StringBuffer strBuf = new StringBuffer();//用于接收信息
187 int len = -1;
188 boolean isFirst = true;
189 boolean isOk = false;
190 flagb[0] = flag;
191 while(true)
192 {
193 //第一次
194 if(isFirst)
195 {
196 isFirst = false;
197 }else
198 {
199 len = socketIn.read(flagb,0,1);//读取标识位
200 if(len != 1)
201 {
202 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
203 break;
204 }
205 }
206 //读取数据长度
207 if(flagb[0]==AUPD.MARK_DATA_SECT)
208 {
209 len = socketIn.read(lenb, 0, 4);
210 if (len != 4)
211 {
212 Config.print(socket.getInetAddress() + ":读取数据头部失败");
213 break;
214 }
215 }
216 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
217 {
218 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
219 byte data[] = new byte[cLen];
220 len = socketIn.read(data, 0, cLen);
221 System.out.println("len:"+len+"cLen="+cLen+">>"+new String(data,0,len));
222 int totLen = len;
223 while (totLen < cLen)//不足位要重重读取
224 {
225 strBuf.append(new String(data, 0, len));
226 len = socketIn.read(data, 0, cLen - totLen);
227 totLen = totLen + len;
228 System.out.println("len:"+len+"cLen="+cLen);
229 }
230 strBuf.append(new String(data, 0, len));
231 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
232 {
233 isOk = true;
234 break;
235 }else
236 {
237 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
238 break;
239 }
240 }//END while(true)
241 if(isOk)//成功
242 {
243 absPath = strBuf.toString();
244 }else//失败
245 {
246 socketOut.write(Config.getCmd(AUPD.BYE));//结束
247 }
248 }catch(Exception e)
249 {
250 Config.print("接收文件全路径处理失败,"+e);
251 }
252 return absPath;
253 }
254 private boolean receiveFile(byte flag)
255 {
256 try
257 {
258 if(currFileAbs==null||currFileAbs.equals(""))
259 {
260 Config.print("无法获取更新文件信息,更新失败");
261 return false;
262 }
263 File file;
264 //先检查目录是否存在
265 //得到目录
266 int idx = currFileAbs.lastIndexOf(File.separator);
267 String path = currFileAbs.substring(0,idx);
268 file = new File(path);
269 if(!file.isDirectory() || !file.exists())
270 {
271 Config.print("新创建目录:"+path);
272 file.mkdir();
273 }
274 file = new File(currFileAbs);
275 FileOutputStream fout = new FileOutputStream(file);
276 //接收数据缓冲区
277 byte flagb[] = new byte[1];//标志
278 byte lenb [] = new byte[4];//长度
279 int len = -1;
280 boolean isFirst = true;
281 boolean isOk = false;
282 flagb[0] = flag;
283 //接收上传的文件数据
284 while (true)
285 {
286 //第一次
287 if(isFirst)
288 {
289 isFirst = false;
290 }else
291 {
292 len = socketIn.read(flagb,0,1);//读取标识位
293 if(len != 1)
294 {
295 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
296 break;
297 }
298 }
299 //读取数据长度
300 if(flagb[0]==AUPD.MARK_DATA_SECT)
301 {
302 len = socketIn.read(lenb, 0, 4);
303 if (len != 4)
304 {
305 Config.print(socket.getInetAddress() + ":读取数据头部失败");
306 break;
307 }
308 }
309 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
310 {
311 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
312 byte data[] = new byte[cLen];
313 len = socketIn.read(data, 0, cLen);
314 int totLen = len;
315 while (totLen < cLen)//不足位要重重读取
316 {
317 fout.write(data,0,len);
318 len = socketIn.read(data, 0, cLen - totLen);
319 totLen = totLen + len;
320 }
321 fout.write(data,0,len);
322 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
323 {
324 isOk = true;
325 break;
326 }else
327 {
328 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
329 break;
330 }
331 }//END while
332 fout.flush();
333 fout.close();
334 if(isOk)
335 {
336 Config.print("成功更新文件:"+file.getAbsolutePath());
337 return true;
338 }else
339 {
340 Config.print("更新文件:"+file.getAbsolutePath()+"失败");
341 return false;
342 }
343 }catch(Exception e)
344 {
345 Config.print("下载更新文件'"+currFileAbs+"'失败,"+e);
346 e.printStackTrace();
347 return false;
348 }
349 }
350 //发送客户端版本信息
351 private void sendClientVer()
352 {
353 try
354 {
355 File verFile = new File(Config.cfgFile);
356 if(!verFile.isFile() || !verFile.exists())
357 {
358 Config.print("版本信息文件不存在");
359 return;
360 }
361 //开始发送
362 FileInputStream fis = new FileInputStream(verFile);
363 byte buffer[] = new byte[AUPD.BUFFER_SIZE];
364 byte data[] = new byte[AUPD.DATA_SIZE];
365 int len = 0;
366 while((len=fis.read(data))!=-1)
367 {
368 //标识为数据段
369 buffer[0] = AUPD.MARK_DATA_SECT;
370 Config.copyArray(buffer,Config.getLen(len),1,0,4);//4位长度
371 //组合数据包
372 for (int i=0; i<len; i++)
373 buffer[i+5] = data[i];//前五位为头部1位标识+4位长度
374 socketOut.write(buffer,0,len+5);//发送数据
375 }//END while
376 //标识为数据段已结束,并发送至服务器
377 buffer[0] = AUPD.MARK_DATA_END;
378 socketOut.write(buffer,0,1);
379 socketOut.flush();
380 fis.close();
381 Config.print("版本信息传送完毕");
382 }catch(Exception e)
383 {
384 Config.print("发送版本信息给服务器失败,"+e);
385 e.printStackTrace();
386 }
387 }
388 //测试主流程
389 public static void main(String args[])
390 {
391 AutoUpdateClient client = new AutoUpdateClient();
392 client.update();
393 }
394}
2 * 项目名称 :rochoc<p>
3 * 包名称 :com.rochoc.autoupdate<p>
4 * 文件名称 :AutoUpdateClient.java<p>
5 * 编写者 :kfzx-luoc<p>
6 * 编写日期 :2008-12-23<p>
7 * 程序功能(类)描述 :<p>
8 * 自动升级客户端对像
9 * 程序变更日期 :
10 * 变更作者 :
11 * 变更说明 :
12********************************************************************/
13 package com.rochoc.autoupdate;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.FileOutputStream;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.net.Socket;
21
22 /** */ /**
23 * @author kfzx-luoc
24 *
25 * TODO To change the template for this generated type comment go to
26 * Window - Preferences - Java - Code Style - Code Templates
27 */
28 public class AutoUpdateClient
29 {
30 private Socket socket = null;
31 private OutputStream socketOut;
32 private InputStream socketIn;
33 private Config config = Config.getInstance();//配置文件对像
34 private String currFileAbs = "";//当前更新文件的全路径
35 public AutoUpdateClient()
36 {
37 try
38 {
39 socket = new Socket(config.getServerIp(),Integer.parseInt(config.getServerPort()));
40 socket.setSoTimeout(30000);//30秒
41 }catch(Exception e)
42 {
43 Config.print("创建与自动升级服务器之间的连接失败,"+e);
44 e.printStackTrace();
45 }
46 }
47 public void update()
48 {
49 if(socket == null)
50 {
51 Config.print("无法与服务器连接,升级失败");
52 return;
53 }
54 try
55 {
56 socketOut = socket.getOutputStream();
57 socketIn = socket.getInputStream();
58
59 //开始升级处理
60 byte flag [] = new byte[1];
61 byte cmd[] = new byte[8];//命令
62 byte datahead [] = new byte[5];//数据头部,第一位用于标识是数据,后四位为长度
63 byte buffer[] = new byte[AUPD.BUFFER_SIZE];//存放数据头部和数据头部
64 byte data[] = new byte[AUPD.DATA_SIZE];//存放具体的数据内容
65 //发送本地版本信息给服务器
66 socketOut.write(Config.getCmd(AUPD.SEND_CLIENT_VERSION));//发送传输版本信息命令
67 sendClientVer();//发送版本信息
68 while(true)
69 {
70 //读取信息
71 int len = socketIn.read(flag,0,1);
72 if(len!=1)
73 {
74 Config.print("读取标识位失败");
75 socketOut.write(Config.getCmd(AUPD.BYE));//结束
76 break;
77 }
78 if(flag[0]==AUPD.CMD_DATA_SECT)//命令行
79 {
80 len = socketIn.read(cmd,0,8);
81 if(len!=8)
82 {
83 Config.print("读取命令失败");
84 socketOut.write(Config.getCmd(AUPD.BYE));//结束
85 break;
86 }
87 if(Config.parseCmd(cmd).equals(AUPD.RECEIVED_CLIENT_VERSION))//收到版本信息
88 {
89 Config.print("服务器成功收到版本信息");
90 socketOut.write(Config.getCmd(AUPD.READY_TO_UPDATE));
91 continue;
92 }else if(Config.parseCmd(cmd).equals(AUPD.SEND_FILE_ABSOULT))//接收文件全路径
93 {
94 Config.print("开始接收文件路径名");
95 }else if(Config.parseCmd(cmd).equals(AUPD.UPDATED_FAILURE))//更新失败
96 {
97 Config.print("版本更新失败");
98 socketOut.write(Config.getCmd(AUPD.BYE));//结束
99 break;
100 }else if(Config.parseCmd(cmd).equals(AUPD.UPDATED_SUCCESSFUL))//更新成功
101 {
102 Config.print("版本更新成功");
103 socketOut.write(Config.getCmd(AUPD.BYE));//结束
104 //打开最新信息
105 openFile(".\\config\\history.htm");
106 break;
107 }else if(Config.parseCmd(cmd).equals(AUPD.NOTNEED_UPDATED))//无需更新
108 {
109 Config.print("已经是最新版本,无需更新");
110 socketOut.write(Config.getCmd(AUPD.BYE));//结束
111 break;
112 }else if(Config.parseCmd(cmd).equals(AUPD.BYE))//结束链接
113 {
114 socketOut.write(Config.getCmd(AUPD.BYE));//结束
115 break;
116 }
117 }else if(flag[0]==AUPD.MARK_DATA_SECT || flag[0]==AUPD.MARK_DATA_END)//数据内容
118 {
119 if(Config.parseCmd(cmd).equals(AUPD.SEND_FILE_ABSOULT))//接收文件全路径
120 {
121 currFileAbs = receiveFileAbsPath(flag[0]);
122 if(currFileAbs!=null && !currFileAbs.equals(""))//成功
123 {
124 socketOut.write(Config.getCmd(AUPD.RECEIVED_FILE_ABSOULT));
125 Config.print("接收文件全路径‘"+currFileAbs+"’成功");
126 }else
127 {
128 Config.print("接收文件全路径失败");
129 socketOut.write(Config.getCmd(AUPD.BYE));//结束
130 break;
131 }
132 }else if(Config.parseCmd(cmd).equals(AUPD.START_TRANSMIT))//接收文件
133 {
134 if(receiveFile(flag[0]))
135 {
136 socketOut.write(Config.getCmd(AUPD.TERMINATE_TRANSMIT));
137 }else
138 {
139 socketOut.write(Config.getCmd(AUPD.BYE));
140 }
141 }else
142 {
143 Config.print("出现非期望数据,"+new String(cmd));
144 socketOut.write(Config.getCmd(AUPD.BYE));//结束
145 break;
146 }
147 }else
148 {
149 Config.print("非期望标识位,"+flag[0]);
150 socketOut.write(Config.getCmd(AUPD.BYE));//结束
151 break;
152 }
153 }//END while(true)
154
155 //关闭资源及链接
156 socketOut.close();
157 socketIn.close();
158 socket.close();
159 Config.print("自动升级处理完毕");
160 }catch(Exception e)
161 {
162 Config.print("升级处理失败,"+e);
163 e.printStackTrace();
164 }
165 }
166 private void openFile(String file)
167 {
168 try
169 {
170 Runtime.getRuntime().exec("cmd /c "+file);
171 }catch(Exception e)
172 {
173 e.printStackTrace();
174 }
175 }
176 private String receiveFileAbsPath(byte flag)
177 {
178 String absPath = "";
179 //接收文件全路径
180 try
181 {
182 //接收数据缓冲区
183 byte flagb[] = new byte[1];//标志
184 byte lenb [] = new byte[4];//长度
185 //接收文件全路径
186 StringBuffer strBuf = new StringBuffer();//用于接收信息
187 int len = -1;
188 boolean isFirst = true;
189 boolean isOk = false;
190 flagb[0] = flag;
191 while(true)
192 {
193 //第一次
194 if(isFirst)
195 {
196 isFirst = false;
197 }else
198 {
199 len = socketIn.read(flagb,0,1);//读取标识位
200 if(len != 1)
201 {
202 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
203 break;
204 }
205 }
206 //读取数据长度
207 if(flagb[0]==AUPD.MARK_DATA_SECT)
208 {
209 len = socketIn.read(lenb, 0, 4);
210 if (len != 4)
211 {
212 Config.print(socket.getInetAddress() + ":读取数据头部失败");
213 break;
214 }
215 }
216 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
217 {
218 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
219 byte data[] = new byte[cLen];
220 len = socketIn.read(data, 0, cLen);
221 System.out.println("len:"+len+"cLen="+cLen+">>"+new String(data,0,len));
222 int totLen = len;
223 while (totLen < cLen)//不足位要重重读取
224 {
225 strBuf.append(new String(data, 0, len));
226 len = socketIn.read(data, 0, cLen - totLen);
227 totLen = totLen + len;
228 System.out.println("len:"+len+"cLen="+cLen);
229 }
230 strBuf.append(new String(data, 0, len));
231 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
232 {
233 isOk = true;
234 break;
235 }else
236 {
237 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
238 break;
239 }
240 }//END while(true)
241 if(isOk)//成功
242 {
243 absPath = strBuf.toString();
244 }else//失败
245 {
246 socketOut.write(Config.getCmd(AUPD.BYE));//结束
247 }
248 }catch(Exception e)
249 {
250 Config.print("接收文件全路径处理失败,"+e);
251 }
252 return absPath;
253 }
254 private boolean receiveFile(byte flag)
255 {
256 try
257 {
258 if(currFileAbs==null||currFileAbs.equals(""))
259 {
260 Config.print("无法获取更新文件信息,更新失败");
261 return false;
262 }
263 File file;
264 //先检查目录是否存在
265 //得到目录
266 int idx = currFileAbs.lastIndexOf(File.separator);
267 String path = currFileAbs.substring(0,idx);
268 file = new File(path);
269 if(!file.isDirectory() || !file.exists())
270 {
271 Config.print("新创建目录:"+path);
272 file.mkdir();
273 }
274 file = new File(currFileAbs);
275 FileOutputStream fout = new FileOutputStream(file);
276 //接收数据缓冲区
277 byte flagb[] = new byte[1];//标志
278 byte lenb [] = new byte[4];//长度
279 int len = -1;
280 boolean isFirst = true;
281 boolean isOk = false;
282 flagb[0] = flag;
283 //接收上传的文件数据
284 while (true)
285 {
286 //第一次
287 if(isFirst)
288 {
289 isFirst = false;
290 }else
291 {
292 len = socketIn.read(flagb,0,1);//读取标识位
293 if(len != 1)
294 {
295 Config.print(socket.getInetAddress() + ":读取数据标识位失败");
296 break;
297 }
298 }
299 //读取数据长度
300 if(flagb[0]==AUPD.MARK_DATA_SECT)
301 {
302 len = socketIn.read(lenb, 0, 4);
303 if (len != 4)
304 {
305 Config.print(socket.getInetAddress() + ":读取数据头部失败");
306 break;
307 }
308 }
309 if (flagb[0] == AUPD.MARK_DATA_SECT)//数据内容
310 {
311 int cLen = Integer.parseInt(new String(lenb, 0, 4));//数据内容长度
312 byte data[] = new byte[cLen];
313 len = socketIn.read(data, 0, cLen);
314 int totLen = len;
315 while (totLen < cLen)//不足位要重重读取
316 {
317 fout.write(data,0,len);
318 len = socketIn.read(data, 0, cLen - totLen);
319 totLen = totLen + len;
320 }
321 fout.write(data,0,len);
322 }else if(flagb[0]==AUPD.MARK_DATA_END)//数据结束
323 {
324 isOk = true;
325 break;
326 }else
327 {
328 Config.print(socket.getInetAddress()+":收到非期望数据,"+new String(flagb,0,1)+"<<");
329 break;
330 }
331 }//END while
332 fout.flush();
333 fout.close();
334 if(isOk)
335 {
336 Config.print("成功更新文件:"+file.getAbsolutePath());
337 return true;
338 }else
339 {
340 Config.print("更新文件:"+file.getAbsolutePath()+"失败");
341 return false;
342 }
343 }catch(Exception e)
344 {
345 Config.print("下载更新文件'"+currFileAbs+"'失败,"+e);
346 e.printStackTrace();
347 return false;
348 }
349 }
350 //发送客户端版本信息
351 private void sendClientVer()
352 {
353 try
354 {
355 File verFile = new File(Config.cfgFile);
356 if(!verFile.isFile() || !verFile.exists())
357 {
358 Config.print("版本信息文件不存在");
359 return;
360 }
361 //开始发送
362 FileInputStream fis = new FileInputStream(verFile);
363 byte buffer[] = new byte[AUPD.BUFFER_SIZE];
364 byte data[] = new byte[AUPD.DATA_SIZE];
365 int len = 0;
366 while((len=fis.read(data))!=-1)
367 {
368 //标识为数据段
369 buffer[0] = AUPD.MARK_DATA_SECT;
370 Config.copyArray(buffer,Config.getLen(len),1,0,4);//4位长度
371 //组合数据包
372 for (int i=0; i<len; i++)
373 buffer[i+5] = data[i];//前五位为头部1位标识+4位长度
374 socketOut.write(buffer,0,len+5);//发送数据
375 }//END while
376 //标识为数据段已结束,并发送至服务器
377 buffer[0] = AUPD.MARK_DATA_END;
378 socketOut.write(buffer,0,1);
379 socketOut.flush();
380 fis.close();
381 Config.print("版本信息传送完毕");
382 }catch(Exception e)
383 {
384 Config.print("发送版本信息给服务器失败,"+e);
385 e.printStackTrace();
386 }
387 }
388 //测试主流程
389 public static void main(String args[])
390 {
391 AutoUpdateClient client = new AutoUpdateClient();
392 client.update();
393 }
394}
看来源码还是有点多,只能再分一次了,否则电脑就快死机了,余下见(四)。