FtpSurveillance.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. using Newtonsoft.Json.Linq;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using System.Xml.Linq;
  13. namespace FtpSurveillance
  14. {
  15. public class FTPOperation
  16. {
  17. public static JArray fileStringArray2 = new JArray();
  18. /// <summary>
  19. /// 通过socket判断ftp是否通畅(异步socket连接,同步发送接收数据 )
  20. /// </summary>
  21. /// <returns></returns>
  22. public string CheckLinkFtp(string ftpip, string serverFTPName, string serverFTPPassword,string port)
  23. {
  24. string errorCode = "0";
  25. string errorMessage = "";
  26. bool checkflag = CheckFtp(ftpip, serverFTPName, serverFTPPassword, out errorMessage, Convert.ToInt32(port));
  27. if (!checkflag)
  28. {
  29. errorCode = "-1";
  30. }
  31. JObject returnobj = new JObject();
  32. returnobj.Add("errorCode", errorCode);
  33. returnobj.Add("errorMessage", errorMessage);
  34. return returnobj.ToString();
  35. }
  36. /// <summary>
  37. /// 通过socket判断ftp是否通畅
  38. /// </summary>
  39. /// <returns></returns>
  40. public static bool CheckFtp(string ip, string ftpuser, string ftppas, out string errmsg, int port = 21)
  41. {
  42. #region 输入数据检查
  43. if (ftpuser.Trim().Length == 0)
  44. {
  45. errmsg = "FTP用户名不能为空,请检查设置!";
  46. return false;
  47. }
  48. if (ftppas.Trim().Length == 0)
  49. {
  50. errmsg = "FTP密码不能为空,请检查设置!";
  51. return false;
  52. }
  53. IPAddress address;
  54. try
  55. {
  56. address = IPAddress.Parse(ip);
  57. }
  58. catch
  59. {
  60. errmsg = string.Format("FTP服务器IP:{0}解析失败,请检查是否设置正确!", ip);
  61. return false;
  62. }
  63. #endregion
  64. bool ret = false;
  65. byte[] result = new byte[1024];
  66. int pingStatus = 0, userStatus = 0, pasStatus = 0, exitStatus = 0; //连接返回,用户名返回,密码返回,退出返回
  67. try
  68. {
  69. int receiveLength;
  70. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  71. socket.SendTimeout = 2000;
  72. socket.ReceiveTimeout = 2000;//超时设置成2000毫秒
  73. try
  74. {
  75. socket.Connect(new IPEndPoint(address, port)); //以21端口进行连接
  76. pingStatus = 200;
  77. }
  78. catch
  79. {
  80. pingStatus = -1;
  81. }
  82. if (pingStatus == 200) //状态码200 - TCP连接成功
  83. {
  84. receiveLength = socket.Receive(result);
  85. pingStatus = getFtpReturnCode(result, receiveLength); //连接状态
  86. if (pingStatus == 220)//状态码220 - FTP返回欢迎语
  87. {
  88. socket.Send(Encoding.Default.GetBytes(string.Format("{0}{1}", "USER " + ftpuser, Environment.NewLine)));
  89. receiveLength = socket.Receive(result);
  90. userStatus = getFtpReturnCode(result, receiveLength);
  91. if (userStatus == 331)//状态码331 - 要求输入密码
  92. {
  93. socket.Send(Encoding.Default.GetBytes(string.Format("{0}{1}", "PASS " + ftppas, Environment.NewLine)));
  94. receiveLength = socket.Receive(result);
  95. pasStatus = getFtpReturnCode(result, receiveLength);
  96. if (pasStatus == 230)//状态码230 - 登入因特网
  97. {
  98. errmsg = string.Format("FTP:{0}@{1}登陆成功", ip, port);
  99. ret = true;
  100. socket.Send(Encoding.Default.GetBytes(string.Format("{0}{1}", "QUIT", Environment.NewLine))); //登出FTP
  101. receiveLength = socket.Receive(result);
  102. exitStatus = getFtpReturnCode(result, receiveLength);
  103. }
  104. else
  105. { // 状态码230的错误
  106. errmsg = string.Format("FTP:{0}@{1}登陆失败,用户名或密码错误({2})", ip, port, pasStatus);
  107. }
  108. }
  109. else
  110. {// 状态码331的错误
  111. errmsg = string.Format("使用用户名:‘{0}‘登陆FTP:{1}@{2}时发生错误({3}),请检查FTP是否正常配置!", ftpuser, ip, port, userStatus);
  112. }
  113. }
  114. else
  115. {// 状态码220的错误
  116. errmsg = string.Format("FTP:{0}@{1}返回状态错误({2}),请检查FTP服务是否正常运行!", ip, port, pingStatus);
  117. }
  118. }
  119. else
  120. {// 状态码200的错误
  121. errmsg = string.Format("无法连接FTP服务器:{0}@{1},请检查FTP服务是否启动!", ip, port);
  122. }
  123. socket.Close(); //关闭socket
  124. socket = null;
  125. }
  126. catch (Exception ex)
  127. { //连接出错
  128. errmsg = string.Format("FTP:{0}@{1}连接出错:", ip, port) + ex.Message;
  129. ret = false;
  130. }
  131. return ret;
  132. }
  133. /// <summary>
  134. /// 传递FTP返回的byte数组和长度,返回状态码(int)
  135. /// </summary>
  136. /// <param name="retByte"></param>
  137. /// <param name="retLen"></param>
  138. /// <returns></returns>
  139. private static int getFtpReturnCode(byte[] retByte, int retLen)
  140. {
  141. try
  142. {
  143. string str = Encoding.ASCII.GetString(retByte, 0, retLen).Trim();
  144. return int.Parse(str.Substring(0, 3));
  145. }
  146. catch
  147. {
  148. return -1;
  149. }
  150. }
  151. /// <summary>
  152. /// 判断路径是否存在
  153. /// 读取里面所有文件
  154. /// </summary>
  155. /// <param name="path"></param>
  156. public JArray Checkpath(string path,out string errmsg)
  157. {
  158. errmsg = "";
  159. fileStringArray2 = new JArray();
  160. try
  161. {
  162. ///判断选中的是文件还是文件夹
  163. if (File.Exists(path))
  164. {
  165. //是文件
  166. //System.IO.Path.GetExtension("c:\windows\test.txt")'获取扩展名
  167. String fileName = System.IO.Path.GetFileName(path); //'获取文件名
  168. JObject inputObj = new JObject();
  169. inputObj.Add("key", (JToken)fileName);
  170. //string filepath = System.IO.Path.GetDirectoryName(path); //获取文件夹
  171. inputObj.Add("value", path);
  172. fileStringArray2.Add(inputObj);
  173. }
  174. else if (Directory.Exists(path))
  175. {
  176. ///文件夹
  177. if (string.IsNullOrEmpty(path))
  178. {
  179. errmsg="路径不存在!";
  180. }
  181. else
  182. {
  183. DirectoryInfo dir = new DirectoryInfo(path);
  184. if (!dir.Exists)
  185. {
  186. errmsg = "路径不存在!";
  187. }
  188. else
  189. {
  190. string pathService = path;
  191. dir = new DirectoryInfo(pathService);
  192. if (!dir.Exists)
  193. {
  194. errmsg = "路径不存在!";
  195. }
  196. else
  197. {
  198. //读取里面所有文件
  199. GetChildDicsNameService(dir, path, "");
  200. }
  201. }
  202. }
  203. }
  204. }
  205. catch (Exception ex)
  206. {
  207. errmsg = "校验路径文档失败:" + ex.Message;
  208. return fileStringArray2;
  209. }
  210. if (fileStringArray2.Count > 0)
  211. {
  212. //生成文档
  213. return fileStringArray2;
  214. }
  215. return fileStringArray2;
  216. }
  217. public static DirectoryInfo[] GetChildDicsNameService(DirectoryInfo dir, string path, string PathName)
  218. {
  219. FileInfo[] fileArray = dir.GetFiles();
  220. DirectoryInfo[] childDirs = dir.GetDirectories();
  221. FileInfo[] array = fileArray;
  222. foreach (FileInfo file in array)
  223. {
  224. string absolutePath = dir.FullName;
  225. string relativePath = absolutePath.Replace(path, "");
  226. relativePath = relativePath.Replace("\\", "/");
  227. if (relativePath != "")
  228. {
  229. relativePath += "/";
  230. }
  231. string fileName = file.Name;
  232. relativePath = relativePath + fileName;
  233. JObject inputObj = new JObject();
  234. inputObj.Add("key", (JToken)fileName);
  235. inputObj.Add("value", (JToken)relativePath);
  236. inputObj.Add("pathName", (JToken)PathName);
  237. fileStringArray2.Add(inputObj);
  238. }
  239. if (childDirs.Length != 0)
  240. {
  241. DirectoryInfo[] array2 = childDirs;
  242. foreach (DirectoryInfo dirChild in array2)
  243. {
  244. string urlName = PathName;
  245. if (urlName == "")
  246. {
  247. urlName = dirChild.Name;
  248. }
  249. else
  250. {
  251. urlName = urlName + "/" + dirChild.Name;
  252. }
  253. GetChildDicsNameService(dirChild, path, urlName);
  254. }
  255. }
  256. return childDirs;
  257. }
  258. /// <summary>
  259. /// 上传
  260. /// </summary>
  261. /// <param name="filename"></param>
  262. /// filename 文件名
  263. /// ftpRemotePath 到什么路径
  264. /// ftpIP IP 地址
  265. /// ftpUserName 用户名
  266. /// ftpPassWord 密码
  267. public string Upload(string filename, string ftpRemotePath, string ftpIP, string ftpUserName, string ftpPassWord)
  268. {
  269. string errorCode = "0";
  270. string errorMessage = "";
  271. FileInfo fileInf = new FileInfo(filename);
  272. //string uri = ftpPath;
  273. string ftpURI = "ftp://" + ftpIP + "/" + ftpRemotePath + "/";
  274. string uri = ftpURI + fileInf.Name;
  275. FtpWebRequest reqFTP;
  276. string FtpCheckrtn = FtpCheckDirectoryExist(ftpRemotePath, "ftp://" + ftpIP, ftpUserName, ftpPassWord); //生成上传路径
  277. JObject FtpCheckrtnObj = JObject.Parse(FtpCheckrtn);
  278. errorCode = FtpCheckrtnObj["errorCode"].ToString();
  279. if (errorCode != "0")
  280. {
  281. return FtpCheckrtn;
  282. }
  283. reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
  284. reqFTP.Credentials = new NetworkCredential(ftpUserName, ftpPassWord);
  285. reqFTP.KeepAlive = false;
  286. reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
  287. reqFTP.UseBinary = true;
  288. reqFTP.ContentLength = fileInf.Length;
  289. int buffLength = 2048;
  290. byte[] buff = new byte[buffLength];
  291. int contentLen;
  292. FileStream fs = fileInf.OpenRead();
  293. try
  294. {
  295. Stream strm = reqFTP.GetRequestStream();
  296. contentLen = fs.Read(buff, 0, buffLength);
  297. while (contentLen != 0)
  298. {
  299. strm.Write(buff, 0, contentLen);
  300. contentLen = fs.Read(buff, 0, buffLength);
  301. }
  302. strm.Close();
  303. fs.Close();
  304. }
  305. catch (Exception ex)
  306. {
  307. errorCode = "-1";
  308. errorMessage = errorMessage + ";" + uri + ":" + ex.Message;
  309. }
  310. JObject returnobj = new JObject();
  311. returnobj.Add("errorCode", errorCode);
  312. returnobj.Add("errorMessage", errorMessage);
  313. return returnobj.ToString();
  314. }
  315. private string getXMLValue(string path, string attr)
  316. {
  317. string xmlValue = "";
  318. XDocument document = XDocument.Load(path);
  319. XElement root = document.Root;
  320. XElement settingEle = root.Element("appSettings");
  321. IEnumerable<XElement> enumerable = settingEle.Elements();
  322. foreach (XElement item in enumerable)
  323. {
  324. if (item.Attribute("key").Value == attr)
  325. {
  326. xmlValue = item.Attribute("value").Value;
  327. }
  328. }
  329. return xmlValue;
  330. }
  331. public void ExecuteAsAdmin(string fileName)
  332. {
  333. Process proc = new Process();
  334. proc.StartInfo.FileName = fileName;
  335. proc.StartInfo.UseShellExecute = true;
  336. proc.StartInfo.Verb = "runas";
  337. proc.Start();
  338. }
  339. public static string FtpCheckDirectoryExist(string destFilePath, string ftpIP, string ftpUserID, string ftpPassword)
  340. {
  341. JObject jObject = new JObject();
  342. string fullDir = FtpParseDirectory(destFilePath);
  343. string[] dirs = fullDir.Split('/');
  344. string curDir = "/";
  345. string errorCode = "0";
  346. string errorMessage = "";
  347. for (int i = 0; i < dirs.Length; i++)
  348. {
  349. string dir = dirs[i];
  350. //如果是以/开始的路径,第一个为空
  351. if (dir != null && dir.Length > 0)
  352. {
  353. try
  354. {
  355. string URI = ftpIP + curDir;
  356. string flagstring = DirectoryExist(URI, dir, ftpUserID, ftpPassword);
  357. JObject flagsobj = JObject.Parse(flagstring);
  358. if (flagsobj["errorCode"].ToString() == "-1")
  359. {
  360. //不存在就进行创建
  361. string newFilePath = curDir + dir + "/";
  362. MakeDir(newFilePath, ftpIP, ftpUserID, ftpPassword);
  363. }
  364. else if (flagsobj["errorCode"].ToString() != "0")
  365. {
  366. //错误
  367. errorCode = flagsobj["errorCode"].ToString();
  368. errorMessage = flagsobj["errorMessage"].ToString();
  369. break;
  370. }
  371. curDir += dir + "/";
  372. }
  373. catch (Exception ex)
  374. {
  375. errorCode = "-1";
  376. errorMessage = ex.Message;
  377. jObject.Add("errorCode", errorCode);
  378. jObject.Add("errorMessage", errorMessage);
  379. return jObject.ToString();
  380. }
  381. }
  382. }
  383. jObject.Add("errorCode", errorCode);
  384. jObject.Add("errorMessage", errorMessage);
  385. return jObject.ToString();
  386. }
  387. public static string FtpParseDirectory(string destFilePath)
  388. {
  389. return destFilePath.Substring(0, destFilePath.LastIndexOf("/"));
  390. }
  391. /// <summary>
  392. /// 创建文件夹
  393. /// </summary>
  394. /// <param name="dirName"></param>
  395. public static Boolean MakeDir(string curDir, string ftpIP, string ftpUserID, string ftpPassword)
  396. {
  397. FtpWebRequest reqFTP;
  398. string errorCode = "0";
  399. string errorMessage = "";
  400. reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpIP + curDir));
  401. try
  402. {
  403. // dirName = name of the directory to create.
  404. reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
  405. reqFTP.UseBinary = true;
  406. reqFTP.UseBinary = false;
  407. reqFTP.KeepAlive = false;
  408. reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
  409. FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
  410. Stream ftpStream = response.GetResponseStream();
  411. ftpStream.Close();
  412. response.Close();
  413. }
  414. catch (Exception ex)
  415. {
  416. errorCode = "-1";
  417. errorMessage = errorMessage + ";" + ftpIP + "/" + curDir + ":" + ex.Message;
  418. reqFTP.Abort();
  419. return false;
  420. }
  421. reqFTP.Abort();
  422. return true;
  423. }
  424. /// <summary>
  425. /// 检查目录是否存在
  426. /// </summary>
  427. /// <param name="ftpPath">要检查的目录的上一级目录</param>
  428. /// <param name="dirName">要检查的目录名</param>
  429. /// <returns>存在返回true,否则false</returns>
  430. public static string DirectoryExist(string ftpPath, string dirName, string FTPName, string FTPPassword)
  431. {
  432. JObject jObject = new JObject();
  433. string errorCode = "-1";
  434. try
  435. {
  436. //实例化FTP连接
  437. FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpPath));
  438. reqFTP.Credentials = new NetworkCredential(FTPName, FTPPassword);
  439. //指定FTP操作类型为创建目录
  440. reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
  441. //获取FTP服务器的响应
  442. FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
  443. StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
  444. StringBuilder str = new StringBuilder();
  445. string line = sr.ReadLine();
  446. while (line != null)
  447. {
  448. str.Append(line);
  449. str.Append("|");
  450. line = sr.ReadLine();
  451. }
  452. string[] datas = str.ToString().Split('|');
  453. for (int i = 0; i < datas.Length; i++)
  454. {
  455. if (datas[i].Contains("<DIR>"))
  456. {
  457. int index = datas[i].IndexOf("<DIR>");
  458. string name = datas[i].Substring(index + 5).Trim();
  459. if (name == dirName)
  460. {
  461. errorCode = "0";
  462. break;
  463. }
  464. }
  465. }
  466. sr.Close();
  467. sr.Dispose();
  468. response.Close();
  469. }
  470. catch (Exception ex)
  471. {
  472. jObject.Add("errorCode", "-2");
  473. jObject.Add("errorMessage", "MakeDir:" + ftpPath + "/" + dirName + ex.Message);
  474. return jObject.ToString();
  475. }
  476. jObject.Add("errorCode", errorCode);
  477. jObject.Add("errorMessage", "");
  478. return jObject.ToString();
  479. }
  480. }
  481. }