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********************************************************************/
13package com.rochoc.autoupdate;
14
15import java.io.File;
16import java.io.FileInputStream;
17import java.io.IOException;
18import java.io.InputStream;
19import java.io.OutputStream;
20import java.io.StringReader;
21import java.net.Socket;
22import 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 */
30public 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********************************************************************/ 13package com.rochoc.autoupdate; 14 15import java.io.Reader; 16import java.util.List; 17 18import org.dom4j.Document; 19import org.dom4j.Element; 20import 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 */ 28public 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********************************************************************/ 13package com.rochoc.autoupdate; 14 15import java.io.File; 16import java.io.FileInputStream; 17import java.io.FileOutputStream; 18import java.io.InputStream; 19import java.io.OutputStream; 20import 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 */ 28public 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}
看來源碼還是有點多,只能再分一次了,否則電腦就快死機了,余下見(四)。