123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Runtime.Serialization;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Text;
- using System.Threading;
- namespace DllFileSoc
- {
- public class DllSocketFile
- {
-
- public byte[] UploadFile(SocketFileEntity sfe, SocketEntity se,ref string errorinfo)
- {
- Socket filesocket = null;
- try
- {
- if (string.IsNullOrEmpty(sfe.ClientFilePath)|| string.IsNullOrEmpty(se.MacCode))
- {
- return GetFileDatas(1, -1, "初始化异常,未能取到本机文件目录或机台编号!");
- }
- filesocket = ConnServer(sfe, ref errorinfo);
- if (filesocket == null)
- {
- return GetFileDatas(1, -1, errorinfo);
- }
- else
- {
-
- }
- if (!string.IsNullOrEmpty(sfe.ClientFilePath)&& !string.IsNullOrEmpty(sfe.FileName))
- {
- //创建一个文件对象
- FileInfo EzoneFile = new FileInfo(sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName);
- //打开文件流
- FileStream EzoneStream = EzoneFile.OpenRead();
- //EzoneStream.Position = 0;
- long size = EzoneStream.Length;
- byte[] array = new byte[size];//文件
- EzoneStream.Read(array, 0, array.Length);
- string md5 = GetMD5HashFromFile(array);
- EzoneStream.Close();
- EzoneStream = null;
- EzoneFile = null;
- byte[] datas = GetFileDatas(1,md5,se);
- filesocket.Send(datas);//发送文件md5包到服务器进行验证
- int alllen = 0;
- datas = ReadData(filesocket, ref alllen, ref errorinfo);//接收反馈包
- if (datas == null)
- return GetFileDatas(1, -1, errorinfo);
- //byte[] tempstr = new byte[alllen - 32];
- //Array.Copy(datas, 32, tempstr, 0, tempstr.Length);
- byte[] statusdatas = new byte[4];
- Array.Copy(datas, 8, statusdatas, 0, 4);
- //Array.Reverse(statusdatas);//20200920
- int status = BitConverter.ToInt32(statusdatas, 0);
- //if (status == 1 ||status==-1)
- // return datas;
- if (status == 2)//需要上传文件
- {
- datas = GetFileDatas(array);
- //int sendlen=filesocket.Send(datas);//发送文件内容
- if(!SendData(filesocket,datas,ref errorinfo))
- return GetFileDatas(1, -1, errorinfo);
- datas = ReadData(filesocket, ref alllen, ref errorinfo);//接收反馈包
- }
- if(datas==null)
- return GetFileDatas(1, -1, errorinfo);
- return datas;
- }
- else
- {
- return GetFileDatas(1, -1, "本地查找不到文件,上传失败");
- }
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- return GetFileDatas(1, -1, errorinfo);
- }
- finally
- {
- if (filesocket != null)
- filesocket.Close();
- }
- }
- public byte[] DownloadFile(SocketFileEntity sfe, SocketEntity se, ref string errorinfo)
- {
- Socket filesocket = null;
- try
- {
- //sfe.ClientFilePath = "D:\\SocketClientFile";
- //se.MacCode = "XX001";
- if (string.IsNullOrEmpty(sfe.ClientFilePath) || string.IsNullOrEmpty(se.MacCode))
- {
- return GetFileDatas(2, -1, "初始化异常,未能取到本机文件目录或机台编号!");
- }
- filesocket = ConnServer(sfe,ref errorinfo);
- if (filesocket == null)
- {
- return GetFileDatas(1, -1, errorinfo);
- }
- string md5 = "error";
- //创建一个文件对象
- string path = sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName;
- FileInfo EzoneFile = new FileInfo(path);
- if (File.Exists(path))
- {
- //打开文件流
- FileStream EzoneStream = EzoneFile.OpenRead();
- long size = EzoneStream.Length;
- byte[] array = new byte[size];//文件
- EzoneStream.Read(array, 0, array.Length);
- md5 = GetMD5HashFromFile(array);
- EzoneStream.Close();
- EzoneStream = null;
- EzoneFile = null;
- }
-
- int alllen = 0;
- //byte[] datas = GetFileDatas(2,sfe.FileName);
- byte[] datas = GetFileDatas(2,md5, sfe.ServerFileFullPath, sfe.FileName);
- filesocket.Send(datas);//发送下载指令包
- //int md5Result = CheckClentMD5(filesocket, sfe.ClientFilePath, sfe.FileName, ref errorinfo);
- //if (md5Result ==1)//说明本地有相同文件
- //{
- // datas = GetFileDatas(2, 3, "End To DownLoad");
- // filesocket.Send(datas);//发送不需要下载的指令
- // return GetFileDatas(2, 1, "该文件[" + sfe.FileName + "]本地目录下已存在,无需下载!");
- //}
- //else
- //{
- // datas = GetFileDatas(2, 1, "Begin To DownLoad");
- // filesocket.Send(datas);//发送需要下载的指令
- //}
- //接收反馈包(需要下载时)
- datas = ReadData(filesocket, ref alllen, ref errorinfo);
- byte[] statusdatas = new byte[4];
- Array.Copy(datas, 8, statusdatas, 0, 4);
- //Array.Reverse(statusdatas);
-
- int status = BitConverter.ToInt32(statusdatas, 0);
- if (status == 3)//本地已有相同MD5的文件,无需下载
- return GetFileDatas(2, 1, "本地已有文件[" + sfe.FileName + "],无需下载!");
- if (status == 1)//成功则写入本地文件
- {
- //string fileName = System.IO.Path.GetFileName(sfe.FileName);
- byte[] filebytes = new byte[alllen - 12];
- Array.Copy(datas, 12, filebytes, 0, alllen-12);
- FileStream MyFileStream = new FileStream(sfe.ClientFilePath + Path.DirectorySeparatorChar + sfe.FileName, FileMode.Create, FileAccess.Write);
- MyFileStream.Write(filebytes, 0, filebytes.Length);
- MyFileStream.Close();
- MyFileStream = null;
- datas = GetFileDatas(2, 1, "文件[" + sfe.FileName + "]下载成功!");
- //errorinfo = "文件[" + sfe.FileName + "]下载成功!";
- }
- //else
- //{
- // datas = GetFileDatas(2, -1, "文件[" + sfe.FileName + "]下载失败!");
- // //errorinfo = "文件[" + sfe.FileName + "]下载失败!";
- //}
- if (datas == null)
- return GetFileDatas(1, -1, errorinfo);
- return datas;
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- return GetFileDatas(2,-1,errorinfo);
- }
- finally
- {
- if (filesocket != null)
- filesocket.Close();
- }
- }
- public byte[] GetMacFileList(SocketFileEntity sfe, SocketEntity se, ref string errorinfo)
- {
- try
- {
- string filedir = sfe.ClientFilePath;
- DirectoryInfo root = new DirectoryInfo(filedir);
- FileInfo[] files = null;
- if(sfe.FileName==null||sfe.FileName.Trim()=="")
- {
- files = root.GetFiles();
- }
- else
- {
- files = root.GetFiles().Where(t => t.Name.Contains(sfe.FileName)).ToArray();
- }
- List<string> fileslist = new List<string>();
- foreach(var item in files)
- {
- fileslist.Add(item.Name);
- }
- return GetFileDatas(3, 1, fileslist);
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- return GetFileDatas(3, -1, errorinfo);
- }
- }
- private Socket ConnServer(SocketFileEntity sfe,ref string errorinfo)
- {
- try
- {
- IPAddress ip = IPAddress.Parse(sfe.ConnetIp);//服务端所在IP
- //IPEndPoint ipEnd = new IPEndPoint(ip, 5888);//服务端所监听的接口
- IPEndPoint ipEnd = new IPEndPoint(ip, sfe.ConnetPort);//服务端所监听的接口
- Socket CurrSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//初始化一个Socket对象
- CurrSocket.Connect(ipEnd);
- //此语句只支持windows系统,不支持linux系统
- //CurrSocket.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveData(), null);
- ////处理来自机台的包,设置接受超时时间
- CurrSocket.ReceiveTimeout = sfe.SetTimeOut;
- CurrSocket.SendTimeout = sfe.SetTimeOut;
- return CurrSocket;
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- return null;
- }
-
- }
- private int CheckClentMD5(Socket filesocket, string filePath,string fileName,ref string errorinfo)
- {
- try
- {
- FileInfo EzoneFile = new FileInfo(filePath + Path.DirectorySeparatorChar + fileName);
- if (EzoneFile == null)
- return -1;
- FileStream EzoneStream = EzoneFile.OpenRead();
- long size = EzoneStream.Length;
- byte[] array = new byte[size];//文件
- EzoneStream.Read(array, 0, array.Length);
- string clientMd5 = GetMD5HashFromFile(array);
- int allen = 0;
- byte[] datas = ReadData(filesocket, ref allen, ref errorinfo);
- byte[] fileMd5 = new byte[datas.Length - 4];
- Array.Copy(datas, 4, fileMd5,0, fileMd5.Length);
- string serverMd5 = Encoding.UTF8.GetString(fileMd5);
- if (clientMd5== serverMd5)
- {
- return 1;
- }
- else
- {
- return -1;
- }
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- return -1;
- }
-
- }
- /// <summary>
- /// 带有MD5验证的包
- /// </summary>
- /// <param name="mode"></param>
- /// <param name="md5"></param>
- /// <param name="se"></param>
- /// <returns></returns>
- private byte[] GetFileDatas(Int32 mode, string md5,SocketEntity se)
- {
- Dictionary<string, string> dic = new Dictionary<string, string>();
- byte[] msgbytes = Encoding.UTF8.GetBytes(md5);
- dic.Clear();
- dic.Add("fileName",se.FileName);
- dic.Add("macCode", se.MacCode);
- byte[] bytese = SerializeBytes<Dictionary<string, string>>(dic);
- //byte[] bytese= SerializeBytes<SocketEntity>(se);
- Int32 len = bytese.Length + 40;
- byte[] alldatas = BitConverter.GetBytes(len);
-
- byte[] forAll= (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(msgbytes).Concat(bytese)).ToArray();
- //SocketEntity sockE = DeSerializeBytes<SocketEntity>(bytese);
- return forAll;
- }
- private byte[] GetFileDatas(Int32 mode, string md5,string fullpath,string filename)
- {
- Dictionary<string, string> dicFile = new Dictionary<string, string>();
- dicFile.Add("clientMd5", md5);
- dicFile.Add("serverFullpath", fullpath);
- dicFile.Add("serverFilename", filename);
- byte[] msgbytes = SerializeBytes<Dictionary<string, string>>(dicFile);
- //byte[] filefullpath = Encoding.UTF8.GetBytes(fullpath);
- Int32 len = msgbytes.Length + 8;
- byte[] alldatas = BitConverter.GetBytes(len);
- byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(msgbytes)).ToArray();
- //SocketEntity sockE = DeSerializeBytes<SocketEntity>(bytese);
- return forAll;
- }
- private byte[] GetFileDatas( byte[] files)
- {
- //byte[] msgbytes = Encoding.UTF8.GetBytes(msg);
- Int32 len = files.Length + 4;
- byte[] alldatas = BitConverter.GetBytes(len);
- byte[] forAll= (alldatas.Concat(files)).ToArray();
- return forAll;
- }
- private byte[] GetFileDatas(Int32 mode, string filename)
- {
- byte[] files = Encoding.UTF8.GetBytes(filename);//文件名
- Int32 len = files.Length +8;
- byte[] alldatas = BitConverter.GetBytes(len);//总长度
- byte[] md = BitConverter.GetBytes(mode);//指令
- byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(files)).ToArray();
- //return alldatas;
- //byte[] all = new byte[len];
- //Array.Copy(alldatas, 0, all, 0,4);
- //Array.Copy(md, 0, all, 4, 4);
- //Array.Copy(files, 0, all, 8, files.Length);
- return forAll;
- }
- private byte[] GetFileDatas(Int32 mode, Int32 result, string msg)
- {
- byte[] msgbytes = Encoding.UTF8.GetBytes(msg);
- Int32 len = msgbytes.Length + 12;
- byte[] alldatas = BitConverter.GetBytes(len);
- byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(BitConverter.GetBytes(result)).Concat(msgbytes)).ToArray();
- return forAll;
- }
- private byte[] GetFileDatas(Int32 mode, Int32 result, List<string> msg)
- {
- byte[] msgbytes = SerializeBytes<List<string>>(msg);
- Int32 len = msgbytes.Length + 12;
- byte[] alldatas = BitConverter.GetBytes(len);
- byte[] forAll = (alldatas.Concat(BitConverter.GetBytes(mode)).Concat(BitConverter.GetBytes(result)).Concat(msgbytes)).ToArray();
- return forAll;
- }
- //socket读取数据
- private byte[] ReadData(Socket CurrSocket, ref int alllen, ref string errorinfo)
- {
- byte[] allbuffs = null;
- try
- {
- byte[] tempbuff = new byte[4];
- byte[] bytesbuff = new byte[4];
- int result = 0;
- int levlen = 4;
- int zerocount = 0;
- while (levlen > 0)
- {
- //说明前面4位还没接受完,需要继续接受
- result = CurrSocket.Receive(tempbuff, levlen, SocketFlags.None);//先读取4位块长度字节
- if (result == 0 && zerocount <= 20)
- {
- zerocount++;
- //如果返回数据长度为0,则休眠1秒钟,然后继续读取
- Thread.Sleep(1000);
- continue;
- }
- if (result <= 0)
- {
- errorinfo = $"未能从待机程序监听上读取数据,可能机台已经断开了,接受长度={result} ";
- return null;
- }
- if (result < levlen)
- {
- //添加测试代码
- //int a = 10;
- }
- if (result > 0)
- {
- Array.Copy(tempbuff, 0, bytesbuff, 4 - levlen, result);
- }
- levlen = levlen - result;
- }
- //Array.Reverse(bytesbuff);//20200920
- int len = BitConverter.ToInt32(bytesbuff, 0)-4;
- alllen = len;
- if (len > 10)
- {
- int a = 10;
- }
- byte[] buffs = new byte[len];
- tempbuff = new byte[len];
- levlen = len;
- zerocount = 0;
- while (levlen > 0)
- {
- //说明还没接受完,需要继续接受
- result = CurrSocket.Receive(tempbuff, levlen, SocketFlags.None);
- if (result == 0 && zerocount <= 20)
- {
- zerocount++;
- //如果返回数据长度为0,则休眠1秒钟,然后继续读取
- Thread.Sleep(1000);
- continue;
- }
- if (result <= 0)
- {
- errorinfo = $"未能从待机程序监听上读取数据,可能机台已经断开了,接受长度={result} ";
- return null;
- }
- if (result > 0)
- {
- Array.Copy(tempbuff, 0, buffs, len - levlen, result);
- }
- levlen = levlen - result;
- }
- //result =mysocket.Receive(buffs,len,SocketFlags.None);
- //Array.Reverse(bytesbuff);//20200920
- allbuffs = new byte[len + 4];
- Array.Copy(bytesbuff, allbuffs, 4);
- Array.Copy(buffs, 0, allbuffs, 4, len);
- alllen = len + 4;
- return allbuffs;
- }
- catch (SocketException ex)
- {
- errorinfo = "待机程序Socket接受数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
- return null;
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- errorinfo = "待机程序Socket接受数据发生异常,错误信息为:" + errorinfo;
- return null;
- }
- }
- private bool SendData(Socket CurrSocket,byte[] allbytes,ref string errorinfo)
- {
- try
- {
- //包的大小 1MB
- int PacketSize = 1024*1024;
- //包的数量
- int PacketCount = (int)(allbytes.Length / ((long)PacketSize));
- //最后一个包的大小
- int LastDataPacket = (int)(allbytes.Length - ((long)(PacketSize * PacketCount)));
- int satrtNum = 1;
- int len = PacketCount;
- byte[] sendArr = null;
- while (len > 0)
- {
-
- sendArr = new byte[PacketSize];
- Array.Copy(allbytes, (satrtNum - 1) * PacketSize, sendArr, 0, PacketSize);
- //CurrSocket.Send(sendArr);//发送文件内容
- if (!SendDataIt(CurrSocket, sendArr, ref errorinfo))
- return false;
- len = len - 1;
- satrtNum++;
- }
- if (LastDataPacket!=0)
- {
- sendArr = new byte[LastDataPacket];
- Array.Copy(allbytes, PacketCount * PacketSize, sendArr, 0, LastDataPacket);
- //CurrSocket.Send(sendArr);//发送最后一个包
- if (!SendDataIt(CurrSocket, sendArr, ref errorinfo))
- return false;
- }
- return true;
- }
- catch (SocketException ex)
- {
- errorinfo = "待机程序Socket发送数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
- return false;
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- errorinfo = "待机程序Socket发送数据发生异常,错误信息为:" + errorinfo;
- return false;
- }
- }
- private bool SendDataIt(Socket CurrSocket, byte[] allbytes, ref string errorinfo)
- {
- try
- {
- int lenlev = allbytes.Length;
- byte[] tempbytes = null;
- int result = 0;
- while (lenlev > 0)
- {
- tempbytes = new byte[lenlev];
- Array.Copy(allbytes,allbytes.Length-lenlev, tempbytes, 0, lenlev);
- result=CurrSocket.Send(tempbytes);//发送文件内容
- lenlev = lenlev - result;
- }
- return true;
- }
- catch (SocketException ex)
- {
- errorinfo = "Socket发送数据发生异常,错误信息为:" + ex.SocketErrorCode.ToString();
- return false;
- }
- catch (Exception ex)
- {
- errorinfo = ex.Message.ToString();
- errorinfo = "Socket发送数据发生异常,错误信息为:" + errorinfo;
- return false;
- }
- }
- public static string GetMD5HashFromFile(byte[] filedatas)
- {
- try
- {
- System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
- byte[] retVal = md5.ComputeHash(filedatas);
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < retVal.Length; i++)
- {
- sb.Append(retVal[i].ToString("x2"));
- }
- return sb.ToString();
- }
- catch (Exception ex)
- {
- //errorinfo = ex.Message.ToString();
- return "";
- }
- }
-
- public static T DeSerializeBytes<T>(byte[] bytes) where T : class
- {
- MemoryStream stream = new MemoryStream(bytes);
- IFormatter formatter = new BinaryFormatter();
- stream.Seek(0, SeekOrigin.Begin);
- T o = (T)formatter.Deserialize(stream);
- stream.Close();
- return o;
- }
- /// <summary>
- /// 将实体序列化
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj"></param>
- /// <returns></returns>
- public static byte[] SerializeBytes<T>(T obj) where T : class
- {
- MemoryStream stream = new MemoryStream();
- IFormatter formatter = new BinaryFormatter();
- formatter.Serialize(stream, obj);
- stream.Close();
- return stream.ToArray();
- }
- }
- }
|