DllSocketFile.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Runtime.Serialization;
  8. using System.Runtime.Serialization.Formatters.Binary;
  9. using System.Text;
  10. using System.Threading;
  11. namespace DllFileSoc
  12. {
  13. public class DllSocketFile
  14. {
  15. public byte[] UploadFile(SocketFileEntity sfe, SocketEntity se,ref string errorinfo)
  16. {
  17. Socket filesocket = null;
  18. try
  19. {
  20. if (string.IsNullOrEmpty(sfe.ClientFilePath)|| string.IsNullOrEmpty(se.MacCode))
  21. {
  22. return GetFileDatas(1, -1, "初始化异常,未能取到本机文件目录或机台编号!");
  23. }
  24. filesocket = ConnServer(sfe, ref errorinfo);
  25. if (filesocket == null)
  26. {
  27. return GetFileDatas(1, -1, errorinfo);
  28. }
  29. else
  30. {
  31. }
  32. if (!string.IsNullOrEmpty(sfe.ClientFilePath)&& !string.IsNullOrEmpty(sfe.FileName))
  33. {
  34. //创建一个文件对象
  35. FileInfo EzoneFile = new FileInfo(sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName);
  36. //打开文件流
  37. FileStream EzoneStream = EzoneFile.OpenRead();
  38. //EzoneStream.Position = 0;
  39. long size = EzoneStream.Length;
  40. byte[] array = new byte[size];//文件
  41. EzoneStream.Read(array, 0, array.Length);
  42. string md5 = GetMD5HashFromFile(array);
  43. EzoneStream.Close();
  44. EzoneStream = null;
  45. EzoneFile = null;
  46. byte[] datas = GetFileDatas(1,md5,se);
  47. filesocket.Send(datas);//发送文件md5包到服务器进行验证
  48. int alllen = 0;
  49. datas = ReadData(filesocket, ref alllen, ref errorinfo);//接收反馈包
  50. if (datas == null)
  51. return GetFileDatas(1, -1, errorinfo);
  52. //byte[] tempstr = new byte[alllen - 32];
  53. //Array.Copy(datas, 32, tempstr, 0, tempstr.Length);
  54. byte[] statusdatas = new byte[4];
  55. Array.Copy(datas, 8, statusdatas, 0, 4);
  56. //Array.Reverse(statusdatas);//20200920
  57. int status = BitConverter.ToInt32(statusdatas, 0);
  58. //if (status == 1 ||status==-1)
  59. // return datas;
  60. if (status == 2)//需要上传文件
  61. {
  62. datas = GetFileDatas(array);
  63. //int sendlen=filesocket.Send(datas);//发送文件内容
  64. if(!SendData(filesocket,datas,ref errorinfo))
  65. return GetFileDatas(1, -1, errorinfo);
  66. datas = ReadData(filesocket, ref alllen, ref errorinfo);//接收反馈包
  67. }
  68. if(datas==null)
  69. return GetFileDatas(1, -1, errorinfo);
  70. return datas;
  71. }
  72. else
  73. {
  74. return GetFileDatas(1, -1, "本地查找不到文件,上传失败");
  75. }
  76. }
  77. catch (Exception ex)
  78. {
  79. errorinfo = ex.Message.ToString();
  80. return GetFileDatas(1, -1, errorinfo);
  81. }
  82. finally
  83. {
  84. if (filesocket != null)
  85. filesocket.Close();
  86. }
  87. }
  88. public byte[] DownloadFile(SocketFileEntity sfe, SocketEntity se, ref string errorinfo)
  89. {
  90. Socket filesocket = null;
  91. try
  92. {
  93. //sfe.ClientFilePath = "D:\\SocketClientFile";
  94. //se.MacCode = "XX001";
  95. if (string.IsNullOrEmpty(sfe.ClientFilePath) || string.IsNullOrEmpty(se.MacCode))
  96. {
  97. return GetFileDatas(2, -1, "初始化异常,未能取到本机文件目录或机台编号!");
  98. }
  99. filesocket = ConnServer(sfe,ref errorinfo);
  100. if (filesocket == null)
  101. {
  102. return GetFileDatas(1, -1, errorinfo);
  103. }
  104. string md5 = "error";
  105. //创建一个文件对象
  106. string path = sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName;
  107. FileInfo EzoneFile = new FileInfo(path);
  108. if (File.Exists(path))
  109. {
  110. //打开文件流
  111. FileStream EzoneStream = EzoneFile.OpenRead();
  112. long size = EzoneStream.Length;
  113. byte[] array = new byte[size];//文件
  114. EzoneStream.Read(array, 0, array.Length);
  115. md5 = GetMD5HashFromFile(array);
  116. EzoneStream.Close();
  117. EzoneStream = null;
  118. EzoneFile = null;
  119. }
  120. int alllen = 0;
  121. //byte[] datas = GetFileDatas(2,sfe.FileName);
  122. byte[] datas = GetFileDatas(2,md5, sfe.ServerFileFullPath, sfe.FileName);
  123. filesocket.Send(datas);//发送下载指令包
  124. //int md5Result = CheckClentMD5(filesocket, sfe.ClientFilePath, sfe.FileName, ref errorinfo);
  125. //if (md5Result ==1)//说明本地有相同文件
  126. //{
  127. // datas = GetFileDatas(2, 3, "End To DownLoad");
  128. // filesocket.Send(datas);//发送不需要下载的指令
  129. // return GetFileDatas(2, 1, "该文件[" + sfe.FileName + "]本地目录下已存在,无需下载!");
  130. //}
  131. //else
  132. //{
  133. // datas = GetFileDatas(2, 1, "Begin To DownLoad");
  134. // filesocket.Send(datas);//发送需要下载的指令
  135. //}
  136. //接收反馈包(需要下载时)
  137. datas = ReadData(filesocket, ref alllen, ref errorinfo);
  138. byte[] statusdatas = new byte[4];
  139. Array.Copy(datas, 8, statusdatas, 0, 4);
  140. //Array.Reverse(statusdatas);
  141. int status = BitConverter.ToInt32(statusdatas, 0);
  142. if (status == 3)//本地已有相同MD5的文件,无需下载
  143. return GetFileDatas(2, 1, "本地已有文件[" + sfe.FileName + "],无需下载!");
  144. if (status == 1)//成功则写入本地文件
  145. {
  146. //string fileName = System.IO.Path.GetFileName(sfe.FileName);
  147. byte[] filebytes = new byte[alllen - 12];
  148. Array.Copy(datas, 12, filebytes, 0, alllen-12);
  149. FileStream MyFileStream = new FileStream(sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName, FileMode.Create, FileAccess.Write);
  150. MyFileStream.Write(filebytes, 0, filebytes.Length);
  151. MyFileStream.Close();
  152. MyFileStream = null;
  153. datas = GetFileDatas(2, 1, "文件[" + sfe.FileName + "]下载成功!");
  154. //errorinfo = "文件[" + sfe.FileName + "]下载成功!";
  155. }
  156. //else
  157. //{
  158. // datas = GetFileDatas(2, -1, "文件[" + sfe.FileName + "]下载失败!");
  159. // //errorinfo = "文件[" + sfe.FileName + "]下载失败!";
  160. //}
  161. if (datas == null)
  162. return GetFileDatas(1, -1, errorinfo);
  163. return datas;
  164. }
  165. catch (Exception ex)
  166. {
  167. errorinfo = ex.Message.ToString();
  168. return GetFileDatas(2,-1,errorinfo);
  169. }
  170. finally
  171. {
  172. if (filesocket != null)
  173. filesocket.Close();
  174. }
  175. }
  176. public byte[] GetMacFileList(SocketFileEntity sfe, SocketEntity se, ref string errorinfo)
  177. {
  178. try
  179. {
  180. string filedir = sfe.ClientFilePath;
  181. DirectoryInfo root = new DirectoryInfo(filedir);
  182. FileInfo[] files = null;
  183. if(sfe.FileName==null||sfe.FileName.Trim()=="")
  184. {
  185. files = root.GetFiles();
  186. }
  187. else
  188. {
  189. files = root.GetFiles().Where(t => t.Name.Contains(sfe.FileName)).ToArray();
  190. }
  191. List<string> fileslist = new List<string>();
  192. foreach(var item in files)
  193. {
  194. fileslist.Add(item.Name);
  195. }
  196. return GetFileDatas(3, 1, fileslist);
  197. }
  198. catch (Exception ex)
  199. {
  200. errorinfo = ex.Message.ToString();
  201. return GetFileDatas(3, -1, errorinfo);
  202. }
  203. }
  204. private Socket ConnServer(SocketFileEntity sfe,ref string errorinfo)
  205. {
  206. try
  207. {
  208. IPAddress ip = IPAddress.Parse(sfe.ConnetIp);//服务端所在IP
  209. //IPEndPoint ipEnd = new IPEndPoint(ip, 5888);//服务端所监听的接口
  210. IPEndPoint ipEnd = new IPEndPoint(ip, sfe.ConnetPort);//服务端所监听的接口
  211. Socket CurrSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一个Socket对象
  212. CurrSocket.Connect(ipEnd);
  213. //此语句只支持windows系统,不支持linux系统
  214. //CurrSocket.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveData(), null);
  215. ////处理来自机台的包,设置接受超时时间
  216. CurrSocket.ReceiveTimeout = sfe.SetTimeOut;
  217. CurrSocket.SendTimeout = sfe.SetTimeOut;
  218. return CurrSocket;
  219. }
  220. catch (Exception ex)
  221. {
  222. errorinfo = ex.Message.ToString();
  223. return null;
  224. }
  225. }
  226. private int CheckClentMD5(Socket filesocket, string filePath,string fileName,ref string errorinfo)
  227. {
  228. try
  229. {
  230. FileInfo EzoneFile = new FileInfo(filePath + Path.DirectorySeparatorChar + fileName);
  231. if (EzoneFile == null)
  232. return -1;
  233. FileStream EzoneStream = EzoneFile.OpenRead();
  234. long size = EzoneStream.Length;
  235. byte[] array = new byte[size];//文件
  236. EzoneStream.Read(array, 0, array.Length);
  237. string clientMd5 = GetMD5HashFromFile(array);
  238. int allen = 0;
  239. byte[] datas = ReadData(filesocket, ref allen, ref errorinfo);
  240. byte[] fileMd5 = new byte[datas.Length - 4];
  241. Array.Copy(datas, 4, fileMd5,0, fileMd5.Length);
  242. string serverMd5 = Encoding.UTF8.GetString(fileMd5);
  243. if (clientMd5== serverMd5)
  244. {
  245. return 1;
  246. }
  247. else
  248. {
  249. return -1;
  250. }
  251. }
  252. catch (Exception ex)
  253. {
  254. errorinfo = ex.Message.ToString();
  255. return -1;
  256. }
  257. }
  258. /// <summary>
  259. /// 带有MD5验证的包
  260. /// </summary>
  261. /// <param name="mode"></param>
  262. /// <param name="md5"></param>
  263. /// <param name="se"></param>
  264. /// <returns></returns>
  265. private byte[] GetFileDatas(Int32 mode, string md5,SocketEntity se)
  266. {
  267. Dictionary<string, string> dic = new Dictionary<string, string>();
  268. byte[] msgbytes = Encoding.UTF8.GetBytes(md5);
  269. dic.Clear();
  270. dic.Add("fileName",se.FileName);
  271. dic.Add("macCode", se.MacCode);
  272. byte[] bytese = SerializeBytes<Dictionary<string, string>>(dic);
  273. //byte[] bytese= SerializeBytes<SocketEntity>(se);
  274. Int32 len = bytese.Length + 40;
  275. byte[] alldatas = BitConverter.GetBytes(len);
  276. byte[] forAll= (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(msgbytes).Concat(bytese)).ToArray();
  277. //SocketEntity sockE = DeSerializeBytes<SocketEntity>(bytese);
  278. return forAll;
  279. }
  280. private byte[] GetFileDatas(Int32 mode, string md5,string fullpath,string filename)
  281. {
  282. Dictionary<string, string> dicFile = new Dictionary<string, string>();
  283. dicFile.Add("clientMd5", md5);
  284. dicFile.Add("serverFullpath", fullpath);
  285. dicFile.Add("serverFilename", filename);
  286. byte[] msgbytes = SerializeBytes<Dictionary<string, string>>(dicFile);
  287. //byte[] filefullpath = Encoding.UTF8.GetBytes(fullpath);
  288. Int32 len = msgbytes.Length + 8;
  289. byte[] alldatas = BitConverter.GetBytes(len);
  290. byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(msgbytes)).ToArray();
  291. //SocketEntity sockE = DeSerializeBytes<SocketEntity>(bytese);
  292. return forAll;
  293. }
  294. private byte[] GetFileDatas( byte[] files)
  295. {
  296. //byte[] msgbytes = Encoding.UTF8.GetBytes(msg);
  297. Int32 len = files.Length + 4;
  298. byte[] alldatas = BitConverter.GetBytes(len);
  299. byte[] forAll= (alldatas.Concat(files)).ToArray();
  300. return forAll;
  301. }
  302. private byte[] GetFileDatas(Int32 mode, string filename)
  303. {
  304. byte[] files = Encoding.UTF8.GetBytes(filename);//文件名
  305. Int32 len = files.Length +8;
  306. byte[] alldatas = BitConverter.GetBytes(len);//总长度
  307. byte[] md = BitConverter.GetBytes(mode);//指令
  308. byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(files)).ToArray();
  309. //return alldatas;
  310. //byte[] all = new byte[len];
  311. //Array.Copy(alldatas, 0, all, 0,4);
  312. //Array.Copy(md, 0, all, 4, 4);
  313. //Array.Copy(files, 0, all, 8, files.Length);
  314. return forAll;
  315. }
  316. private byte[] GetFileDatas(Int32 mode, Int32 result, string msg)
  317. {
  318. byte[] msgbytes = Encoding.UTF8.GetBytes(msg);
  319. Int32 len = msgbytes.Length + 12;
  320. byte[] alldatas = BitConverter.GetBytes(len);
  321. byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(BitConverter.GetBytes(result)).Concat(msgbytes)).ToArray();
  322. return forAll;
  323. }
  324. private byte[] GetFileDatas(Int32 mode, Int32 result, List<string> msg)
  325. {
  326. byte[] msgbytes = SerializeBytes<List<string>>(msg);
  327. Int32 len = msgbytes.Length + 12;
  328. byte[] alldatas = BitConverter.GetBytes(len);
  329. byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(BitConverter.GetBytes(result)).Concat(msgbytes)).ToArray();
  330. return forAll;
  331. }
  332. //socket读取数据
  333. private byte[] ReadData(Socket CurrSocket, ref int alllen, ref string errorinfo)
  334. {
  335. byte[] allbuffs = null;
  336. try
  337. {
  338. byte[] tempbuff = new byte[4];
  339. byte[] bytesbuff = new byte[4];
  340. int result = 0;
  341. int levlen = 4;
  342. int zerocount = 0;
  343. while (levlen > 0)
  344. {
  345. //说明前面4位还没接受完,需要继续接受
  346. result = CurrSocket.Receive(tempbuff, levlen, SocketFlags.None);//先读取4位块长度字节
  347. if (result == 0 && zerocount <= 20)
  348. {
  349. zerocount++;
  350. //如果返回数据长度为0,则休眠1秒钟,然后继续读取
  351. Thread.Sleep(1000);
  352. continue;
  353. }
  354. if (result <= 0)
  355. {
  356. errorinfo = $"未能从待机程序监听上读取数据,可能机台已经断开了,接受长度={result} ";
  357. return null;
  358. }
  359. if (result < levlen)
  360. {
  361. //添加测试代码
  362. //int a = 10;
  363. }
  364. if (result > 0)
  365. {
  366. Array.Copy(tempbuff, 0, bytesbuff, 4 - levlen, result);
  367. }
  368. levlen = levlen - result;
  369. }
  370. //Array.Reverse(bytesbuff);//20200920
  371. int len = BitConverter.ToInt32(bytesbuff, 0)-4;
  372. alllen = len;
  373. if (len > 10)
  374. {
  375. int a = 10;
  376. }
  377. byte[] buffs = new byte[len];
  378. tempbuff = new byte[len];
  379. levlen = len;
  380. zerocount = 0;
  381. while (levlen > 0)
  382. {
  383. //说明还没接受完,需要继续接受
  384. result = CurrSocket.Receive(tempbuff, levlen, SocketFlags.None);
  385. if (result == 0 && zerocount <= 20)
  386. {
  387. zerocount++;
  388. //如果返回数据长度为0,则休眠1秒钟,然后继续读取
  389. Thread.Sleep(1000);
  390. continue;
  391. }
  392. if (result <= 0)
  393. {
  394. errorinfo = $"未能从待机程序监听上读取数据,可能机台已经断开了,接受长度={result} ";
  395. return null;
  396. }
  397. if (result > 0)
  398. {
  399. Array.Copy(tempbuff, 0, buffs, len - levlen, result);
  400. }
  401. levlen = levlen - result;
  402. }
  403. //result =mysocket.Receive(buffs,len,SocketFlags.None);
  404. //Array.Reverse(bytesbuff);//20200920
  405. allbuffs = new byte[len + 4];
  406. Array.Copy(bytesbuff, allbuffs, 4);
  407. Array.Copy(buffs, 0, allbuffs, 4, len);
  408. alllen = len + 4;
  409. return allbuffs;
  410. }
  411. catch (SocketException ex)
  412. {
  413. errorinfo = "待机程序Socket接受数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
  414. return null;
  415. }
  416. catch (Exception ex)
  417. {
  418. errorinfo = ex.Message.ToString();
  419. errorinfo = "待机程序Socket接受数据发生异常,错误信息为:" + errorinfo;
  420. return null;
  421. }
  422. }
  423. private bool SendData(Socket CurrSocket,byte[] allbytes,ref string errorinfo)
  424. {
  425. try
  426. {
  427. //包的大小 1MB
  428. int PacketSize = 1024*1024;
  429. //包的数量
  430. int PacketCount = (int)(allbytes.Length / ((long)PacketSize));
  431. //最后一个包的大小
  432. int LastDataPacket = (int)(allbytes.Length - ((long)(PacketSize * PacketCount)));
  433. int satrtNum = 1;
  434. int len = PacketCount;
  435. byte[] sendArr = null;
  436. while (len > 0)
  437. {
  438. sendArr = new byte[PacketSize];
  439. Array.Copy(allbytes, (satrtNum - 1) * PacketSize, sendArr, 0, PacketSize);
  440. //CurrSocket.Send(sendArr);//发送文件内容
  441. if (!SendDataIt(CurrSocket, sendArr, ref errorinfo))
  442. return false;
  443. len = len - 1;
  444. satrtNum++;
  445. }
  446. if (LastDataPacket!=0)
  447. {
  448. sendArr = new byte[LastDataPacket];
  449. Array.Copy(allbytes, PacketCount * PacketSize, sendArr, 0, LastDataPacket);
  450. //CurrSocket.Send(sendArr);//发送最后一个包
  451. if (!SendDataIt(CurrSocket, sendArr, ref errorinfo))
  452. return false;
  453. }
  454. return true;
  455. }
  456. catch (SocketException ex)
  457. {
  458. errorinfo = "待机程序Socket发送数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
  459. return false;
  460. }
  461. catch (Exception ex)
  462. {
  463. errorinfo = ex.Message.ToString();
  464. errorinfo = "待机程序Socket发送数据发生异常,错误信息为:" + errorinfo;
  465. return false;
  466. }
  467. }
  468. private bool SendDataIt(Socket CurrSocket, byte[] allbytes, ref string errorinfo)
  469. {
  470. try
  471. {
  472. int lenlev = allbytes.Length;
  473. byte[] tempbytes = null;
  474. int result = 0;
  475. while (lenlev > 0)
  476. {
  477. tempbytes = new byte[lenlev];
  478. Array.Copy(allbytes,allbytes.Length-lenlev, tempbytes, 0, lenlev);
  479. result=CurrSocket.Send(tempbytes);//发送文件内容
  480. lenlev = lenlev - result;
  481. }
  482. return true;
  483. }
  484. catch (SocketException ex)
  485. {
  486. errorinfo = "Socket发送数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
  487. return false;
  488. }
  489. catch (Exception ex)
  490. {
  491. errorinfo = ex.Message.ToString();
  492. errorinfo = "Socket发送数据发生异常,错误信息为:" + errorinfo;
  493. return false;
  494. }
  495. }
  496. public static string GetMD5HashFromFile(byte[] filedatas)
  497. {
  498. try
  499. {
  500. System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  501. byte[] retVal = md5.ComputeHash(filedatas);
  502. StringBuilder sb = new StringBuilder();
  503. for (int i = 0; i < retVal.Length; i++)
  504. {
  505. sb.Append(retVal[i].ToString("x2"));
  506. }
  507. return sb.ToString();
  508. }
  509. catch (Exception ex)
  510. {
  511. //errorinfo = ex.Message.ToString();
  512. return "";
  513. }
  514. }
  515. public static T DeSerializeBytes<T>(byte[] bytes) where T : class
  516. {
  517. MemoryStream stream = new MemoryStream(bytes);
  518. IFormatter formatter = new BinaryFormatter();
  519. stream.Seek(0, SeekOrigin.Begin);
  520. T o = (T)formatter.Deserialize(stream);
  521. stream.Close();
  522. return o;
  523. }
  524. /// <summary>
  525. /// 将实体序列化
  526. /// </summary>
  527. /// <typeparam name="T"></typeparam>
  528. /// <param name="obj"></param>
  529. /// <returns></returns>
  530. public static byte[] SerializeBytes<T>(T obj) where T : class
  531. {
  532. MemoryStream stream = new MemoryStream();
  533. IFormatter formatter = new BinaryFormatter();
  534. formatter.Serialize(stream, obj);
  535. stream.Close();
  536. return stream.ToArray();
  537. }
  538. }
  539. }