TCP_RemoteDataHandler.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. using System;
  2. using System.Collections.Generic;
  3. //using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using System.Threading;
  9. using LYFZ.Network.EnumerateLibrary;
  10. namespace LYFZ.Network
  11. {
  12. /* /// <summary>
  13. /// 远程数据处理类 主动模式
  14. /// </summary>
  15. public class TCP_RemoteDataHandler
  16. {
  17. private TcpClient client;
  18. public TcpClient Client
  19. {
  20. get { return client; }
  21. set { client = value; }
  22. }
  23. /// <summary>
  24. /// 来至远程的网络数据流
  25. /// </summary>
  26. private NetworkStream streamToClient;
  27. /// <summary>
  28. /// 来至远程的网络数据流
  29. /// </summary>
  30. public NetworkStream StreamToClient
  31. {
  32. get { return streamToClient; }
  33. set { streamToClient = value; }
  34. }
  35. /// <summary>
  36. /// 缓冲字节大小
  37. /// </summary>
  38. private const int bufferSize = 8192;
  39. /// <summary>
  40. /// 缓冲字节大小
  41. /// </summary>
  42. public int BufferSize
  43. {
  44. get { return bufferSize; }
  45. }
  46. /// <summary>
  47. /// 缓冲字节数组
  48. /// </summary>
  49. private byte[] buffer;
  50. /// <summary>
  51. /// 缓冲字节数组
  52. /// </summary>
  53. public byte[] Buffer
  54. {
  55. get { return buffer; }
  56. set { buffer = value; }
  57. }
  58. /// <summary>
  59. /// 协议处理对象
  60. /// </summary>
  61. private TCP_ProtocolHandler handler;
  62. /// <summary>
  63. /// 协议处理对象
  64. /// </summary>
  65. public TCP_ProtocolHandler Handler
  66. {
  67. get { return handler; }
  68. set { handler = value; }
  69. }
  70. /// <summary>
  71. /// 初始化
  72. /// </summary>
  73. /// <param name="client"></param>
  74. public TCP_RemoteDataHandler(TcpClient client)
  75. {
  76. this.client = client;
  77. // 获得流
  78. streamToClient = client.GetStream();
  79. buffer = new byte[BufferSize];
  80. handler = new TCP_ProtocolHandler();
  81. }
  82. /// <summary>
  83. /// 读取信息
  84. /// </summary>
  85. /// <param name="stream"></param>
  86. /// <returns></returns>
  87. public TCP_FileProtocol ReadFileProtocol(NetworkStream stream)
  88. {
  89. int bytesRead=0;
  90. byte[] TempBuffer = new byte[BufferSize]; // 清空缓存,避免脏读
  91. string[] protocolArray = null;
  92. try
  93. {
  94. bytesRead = stream.Read(TempBuffer, 0, BufferSize);
  95. if (bytesRead > 0)
  96. {
  97. string msg = Encoding.Unicode.GetString(TempBuffer, 0, bytesRead);
  98. protocolArray = handler.GetProtocol(msg);//获取完整的协议信息
  99. }
  100. }
  101. catch {
  102. LYFZ.BLL.BLL_FileLogs.WriteMainLogs("服务器端已经断开连接...");
  103. }
  104. TCP_FileProtocol protocol = new TCP_FileProtocol();
  105. if (protocolArray.Length > 0)
  106. {
  107. TCP_ProtocolHelperXML helper = new TCP_ProtocolHelperXML(protocolArray[0]);
  108. protocol = helper.GetProtocol();
  109. }
  110. return protocol;
  111. }
  112. #region 服务器端创建客户端连接
  113. /// <summary>
  114. /// 创建客户端连接
  115. /// </summary>
  116. public void CreateClientConnection()
  117. {
  118. // 打印连接到的客户端信息
  119. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("已收到连接请求:本地终结点 {0} <--收到-- 远程客户终结点 {1} 的连接请求,正在建立连接...", client.Client.LocalEndPoint, client.Client.RemoteEndPoint));
  120. try
  121. {
  122. TCP_FileProtocol protocol = ReadFileProtocol(StreamToClient);
  123. if (protocol.InfoType == InformationType.Message)
  124. {
  125. OnCreateClientConnection(protocol);
  126. }
  127. if (streamToClient != null)
  128. {
  129. streamToClient.Dispose();
  130. }
  131. client.Close();
  132. }
  133. catch (Exception ex)
  134. {
  135. if (streamToClient != null)
  136. {
  137. streamToClient.Dispose();
  138. }
  139. client.Close();
  140. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("错误:{0}", ex.Message));
  141. }
  142. }
  143. /// <summary>
  144. /// 创建客户端连接
  145. /// </summary>
  146. private void OnCreateClientConnection(TCP_FileProtocol protocol)
  147. {
  148. if (protocol.Content.Trim().ToLower() == "Connect".ToLower())
  149. {
  150. try
  151. {
  152. // 获取网络端点表示的 IP 地址和端口号
  153. IPEndPoint endPoint = client.Client.RemoteEndPoint as IPEndPoint;
  154. string thisClientIPAddrss = endPoint.Address.ToString(); //client.Client.RemoteEndPoint.ToString().Split(':')[0];
  155. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("开始与远程客户端建立连接:远程客户IP {0} 和端口 {1},正在建立连接...", thisClientIPAddrss, protocol.ClientPort));
  156. // ServerToClientConnectionStart(thisClientIPAddrss, protocol.ClientPort);//创建服务器到客户端的连接
  157. }
  158. catch (Exception ex)
  159. {
  160. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("错误:{0}", ex.Message));
  161. }
  162. }
  163. }
  164. /// <summary>
  165. /// 创建服务器到客户端的连接
  166. /// </summary>
  167. /// <param name="listener"></param>
  168. protected void ServerToClientConnectionStart(string hostOrIP, int port)
  169. {
  170. TcpClient ServerToClientent = new TcpClient();
  171. System.Net.IPAddress ipaddress = System.Net.IPAddress.Parse(hostOrIP);
  172. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("正在连接{0}:{1} 客户端...", hostOrIP, port));
  173. ServerToClientent.Connect(ipaddress, port); // 与服务器连接
  174. try
  175. {
  176. if (ServerToClientent.Connected)
  177. {
  178. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("服务器已成功与{0}:{1} 客户端,建立TCP连接...", hostOrIP, port));
  179. Thread t = new Thread(new ThreadStart(delegate()
  180. {
  181. TCP_RemoteDataHandler wapper = new TCP_RemoteDataHandler(ServerToClientent);
  182. wapper.BeginRead();
  183. }));
  184. t.IsBackground = true;
  185. t.Start();
  186. }
  187. else {
  188. LYFZ.BLL.BLL_FileLogs.WriteMainLogs("连接失败,请检查网络环境是否正常...");
  189. }
  190. }
  191. catch(Exception ex)
  192. {
  193. LYFZ.BLL.BLL_FileLogs.WriteMainLogs("连接错误:"+ex.Message+",请检查网络环境是否正常...");
  194. }
  195. }
  196. #endregion 服务器端创建客户端连接 -- END
  197. #region 客户端处理来至服务器的连接
  198. /// <summary>
  199. /// 客户端处理方法
  200. /// </summary>
  201. public void ClientConnectionProcess()
  202. {
  203. try
  204. {
  205. TCP_FileProtocol protocol = ReadFileProtocol(StreamToClient);
  206. if (protocol.InfoType == InformationType.Message)
  207. {
  208. if (protocol.Content == "ConnectClient")
  209. {
  210. LYFZ.BLL.BLL_FileLogs.WriteMainLogs("服务已授理连接请求,并连接成功.");
  211. }
  212. }
  213. else {
  214. if (streamToClient != null)
  215. {
  216. streamToClient.Dispose();
  217. }
  218. client.Close();
  219. }
  220. }
  221. catch (Exception ex)
  222. {
  223. if (streamToClient != null)
  224. {
  225. streamToClient.Dispose();
  226. }
  227. client.Close();
  228. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("错误:{0}", ex.Message));
  229. }
  230. }
  231. #endregion
  232. */
  233. #region 客户端发送指令到服务端处理方法
  234. /* /// <summary>
  235. /// 发送指令到服务端并返回服务器的处理结果
  236. /// </summary>
  237. /// <param name="command">要发送到服务器的指令</param>
  238. /// <param name="msgOrParameters">发送到服务器指令的参数或是说明,注:多个参数用 “|”分隔</param>
  239. /// <returns></returns>
  240. public string SendCommandToServer(TransferCommand command = TransferCommand.Message, string msgOrParameters = "Hello", string fileName = "", int port = 8500, LYFZ.Network.EnumerateLibrary.InformationType type = LYFZ.Network.EnumerateLibrary.InformationType.Message)
  241. {
  242. string tempMsg = "";
  243. LYFZ.Network.TCP_FileProtocol msgXML = new Network.TCP_FileProtocol(type, msgOrParameters);
  244. string sendMsg = msgXML.ToString();
  245. byte[] tempSendBuffer = Encoding.Unicode.GetBytes(sendMsg); // 获得缓存
  246. try
  247. {
  248. lock (StreamToClient)
  249. {
  250. StreamToClient.Write(tempSendBuffer, 0, tempSendBuffer.Length); // 将连接请求发往服务器
  251. }
  252. TCP_FileProtocol protocol = ReadFileProtocol(StreamToClient);
  253. if (protocol.InfoType == InformationType.Message)
  254. {
  255. tempMsg = protocol.Content;
  256. }
  257. }
  258. catch
  259. {
  260. LYFZ.BLL.BLL_FileLogs.WriteMainLogs("连接已断开,请检查网络环境是否正常...");
  261. }
  262. return tempMsg;
  263. }*/
  264. #endregion
  265. #region 服务器接收并处理客户端请求
  266. /* /// <summary>
  267. /// 服务器开始进行异步读取
  268. /// </summary>
  269. public void BeginRead()
  270. {
  271. AsyncCallback callBack = new AsyncCallback(OnReadComplete);
  272. streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);
  273. }
  274. /// <summary>
  275. /// 再读取完成时进行回调
  276. /// </summary>
  277. /// <param name="ar"></param>
  278. private void OnReadComplete(IAsyncResult ar)
  279. {
  280. int bytesRead = 0;
  281. if (Client.Connected)
  282. {
  283. try
  284. {
  285. lock (streamToClient)
  286. {
  287. try
  288. {
  289. bytesRead = streamToClient.EndRead(ar);
  290. }
  291. catch {
  292. bytesRead = 0;
  293. }
  294. }
  295. if (bytesRead == 0) {
  296. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(("客户端>" + client.Client.RemoteEndPoint + "已断开连接,读取到0字节"));
  297. }
  298. else
  299. {
  300. string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
  301. Array.Clear(buffer, 0, buffer.Length); // 清空缓存,避免脏读
  302. // 获取protocol数组
  303. try
  304. {
  305. string[] protocolArray = handler.GetProtocol(msg);//获取完整的协议信息
  306. foreach (string pro in protocolArray)
  307. {
  308. // 这里异步调用,不然这里可能会比较耗时
  309. ParameterizedThreadStart start = new ParameterizedThreadStart(handleProtocol);
  310. start.BeginInvoke(pro, null, null);
  311. }
  312. }
  313. catch { }
  314. // 再次调用BeginRead(),完成时调用自身,形成无限循环
  315. lock (streamToClient)
  316. {
  317. AsyncCallback callBack = new AsyncCallback(OnReadComplete);
  318. streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);
  319. }
  320. }
  321. }
  322. catch (Exception ex)
  323. {
  324. if (streamToClient != null)
  325. {
  326. streamToClient.Dispose();
  327. }
  328. client.Close();
  329. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("错误:{0}", ex.Message));
  330. ClientDisconnected();
  331. }
  332. }
  333. else {
  334. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("客户端>" + client.Client.RemoteEndPoint + "已主动断开连接。"));
  335. ClientDisconnected();
  336. }
  337. }
  338. /// <summary>
  339. /// 当客户端连接断开时执行方法
  340. /// </summary>
  341. private void ClientDisconnected() {
  342. //根据实际需要实现相应功能
  343. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("客户端连接断开时执行结果:{0}", "暂无处理!"));
  344. }
  345. /// <summary>
  346. /// 向当前网络流写入数据
  347. /// </summary>
  348. /// <param name="value"></param>
  349. public void StreamWrite(string value)
  350. {
  351. byte[] temp = Encoding.Unicode.GetBytes(value); // 获得缓存
  352. try
  353. {
  354. lock (StreamToClient)
  355. {
  356. StreamToClient.Write(temp, 0, temp.Length); // 将连接请求发往服务器
  357. }
  358. }
  359. catch {
  360. }
  361. }
  362. /// <summary>
  363. /// 服务器读取到端客户端数据后的处理程序protocol
  364. /// </summary>
  365. /// <param name="obj"></param>
  366. private void handleProtocol(object obj)
  367. {
  368. string pro = obj as string;
  369. TCP_ProtocolHelperXML helper = new TCP_ProtocolHelperXML(pro);
  370. TCP_FileProtocol protocol = helper.GetProtocol();
  371. if (protocol.InfoType == InformationType.Message)
  372. {
  373. TCP_FileProtocol returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "服务器已接收到:" + protocol.Content + "...");
  374. StreamWrite(returnProtocol.ToString());
  375. }
  376. else if (protocol.InfoType == InformationType.File)
  377. {
  378. TCP_FileProtocol returnProtocol = TransmissionFileHandling(protocol);
  379. StreamWrite(returnProtocol.ToString());
  380. }
  381. }
  382. /// <summary>
  383. /// 文件传输处理方法
  384. /// </summary>
  385. /// <param name="protocol"></param>
  386. /// <returns></returns>
  387. private TCP_FileProtocol TransmissionFileHandling(TCP_FileProtocol protocol)
  388. {
  389. TCP_FileProtocol returnProtocol = new TCP_FileProtocol();
  390. string Command = protocol.Command.ToString();
  391. string[] GetParameters = protocol.Content.Split('|');
  392. string AvatarSaveFilePath = LYFZ.WinAPI.CustomPublicMethod.BasePath;
  393. switch (Command.ToLower())
  394. {
  395. case "uploadavatar":
  396. AvatarSaveFilePath = LYFZ.WinAPI.CustomPublicMethod.BasePath + "\\Resources\\Avatar\\User\\" + protocol.FileName;
  397. if (receiveFile(protocol, AvatarSaveFilePath))
  398. {
  399. returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "头像上传成功");
  400. }
  401. else
  402. {
  403. returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "头像上传失败!");
  404. }
  405. break;
  406. case "downloadavatar":
  407. AvatarSaveFilePath = LYFZ.WinAPI.CustomPublicMethod.BasePath + "\\Resources\\Avatar\\User\\" + protocol.FileName;
  408. if (sendFile(protocol, AvatarSaveFilePath))
  409. {
  410. returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "头像下载成功!");
  411. }
  412. else
  413. {
  414. returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "头像下载失败!");
  415. }
  416. break;
  417. default: returnProtocol = new Network.TCP_FileProtocol(LYFZ.Network.EnumerateLibrary.InformationType.Message, "文件请求命令:" + Command + "无效!"); break;
  418. }
  419. return returnProtocol;
  420. } */
  421. #endregion
  422. /*
  423. #region 服务器端接收文件方法
  424. /// <summary>
  425. /// 获取连接到远程的流 -- 公共方法
  426. /// </summary>
  427. /// <param name="protocol"></param>
  428. /// <param name="localClient"></param>
  429. /// <returns></returns>
  430. private NetworkStream getStreamToClient(TCP_FileProtocol protocol, out TcpClient localClient)
  431. {
  432. // 获取远程客户端的位置
  433. IPEndPoint endpoint = client.Client.RemoteEndPoint as IPEndPoint;
  434. IPAddress ip = endpoint.Address;
  435. // 使用新端口号,获得远程用于接收文件的端口
  436. // endpoint = new IPEndPoint(ip, protocol.ClientPort);
  437. // 连接到远程客户端
  438. try
  439. {
  440. localClient = new TcpClient();
  441. localClient.Connect(endpoint);
  442. }
  443. catch
  444. {
  445. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("客户端>>{0}文件传输通道连接失败...", client.Client.RemoteEndPoint));
  446. localClient = null;
  447. return null;
  448. }
  449. // 获取发送文件的流
  450. NetworkStream streamToClient = localClient.GetStream();
  451. return streamToClient;
  452. }
  453. /// <summary>
  454. /// 接收文件
  455. /// </summary>
  456. /// <param name="protocol"></param>
  457. /// <param name="fileFullName">文件要保存的完全路径名</param>
  458. private bool receiveFile(TCP_FileProtocol protocol,string fileFullName)
  459. {
  460. try
  461. {
  462. // 连接到远程客户端
  463. TcpClient receiveLocalClient;
  464. // 获取发送文件的流
  465. NetworkStream receiveStreamToClient = getStreamToClient(protocol, out receiveLocalClient);
  466. // 随机生成一个在当前目录下的文件名称
  467. //string path = Environment.CurrentDirectory + "\\" + generateFileName(protocol.FileName);
  468. byte[] fileBuffer = new byte[BufferSize]; // 1024每次收1KB
  469. FileStream fs = new FileStream(fileFullName, FileMode.Create, FileAccess.Write);
  470. // 从缓存buffer中读入到文件流中
  471. int bytesRead;
  472. int totalBytes = 0;
  473. do
  474. {
  475. Array.Clear(fileBuffer, 0, fileBuffer.Length); // 清空缓存,避免脏读
  476. bytesRead = receiveStreamToClient.Read(fileBuffer, 0, BufferSize);
  477. fs.Write(fileBuffer, 0, bytesRead);
  478. totalBytes += bytesRead;
  479. // if (bytesRead > 0)
  480. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("已接收数据:{0} Bytes ,数据来源客户端>>{1}", totalBytes, client.Client.RemoteEndPoint));
  481. } while (bytesRead > 0);
  482. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("共有{0} Bytes 接收的字节数,完成!,数据来源客户端>>{1}", totalBytes, client.Client.RemoteEndPoint));
  483. receiveStreamToClient.Dispose();
  484. fs.Dispose();
  485. receiveLocalClient.Close();
  486. if (totalBytes > 0)
  487. {
  488. return true;
  489. }
  490. else {
  491. return false;
  492. }
  493. }
  494. catch(Exception ex) {
  495. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("接收文件错误:{0}",ex.Message));
  496. return false;
  497. }
  498. }
  499. #endregion
  500. #region 服务器端向客户端发送文件处理方法
  501. /// <summary>
  502. /// 服务器端向客户端发送文件
  503. /// </summary>
  504. /// <param name="protocol"></param>
  505. /// <param name="fileFullName">要发送的文件</param>
  506. private bool sendFile(TCP_FileProtocol protocol, string fileFullName)
  507. {
  508. try
  509. {
  510. TcpClient localClient;
  511. NetworkStream sendStreamToClient = getStreamToClient(protocol, out localClient);
  512. // 获得文件的路径
  513. string filePath = fileFullName;
  514. if (File.Exists(filePath))
  515. {
  516. // 创建文件流
  517. FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  518. byte[] fileBuffer = new byte[BufferSize]; // 每次传1KB
  519. int bytesRead;
  520. int totalBytes = 0;
  521. // 创建获取文件发送状态的类
  522. TCP_SendStatus status = new TCP_SendStatus(filePath);
  523. // 将文件流转写入网络流
  524. try
  525. {
  526. do
  527. {
  528. // Thread.Sleep(1); // 为了更好的视觉效果,暂停1毫秒:-)
  529. Array.Clear(fileBuffer, 0, fileBuffer.Length); // 清空缓存,避免脏读
  530. bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length);
  531. sendStreamToClient.Write(fileBuffer, 0, bytesRead);
  532. totalBytes += bytesRead; // 发送了的字节数
  533. string statusMsg = status.GetStatus(totalBytes); // 打印发送状态
  534. // if (bytesRead > 0)
  535. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("{0} ,数据发往客户端>>{1}", statusMsg, client.Client.RemoteEndPoint));
  536. } while (bytesRead > 0);
  537. // LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("共有{0} Bytes 发送完成!,数据发往客户端>>{1}", totalBytes, client.Client.RemoteEndPoint));
  538. }
  539. catch
  540. {
  541. totalBytes = 0;
  542. LYFZ.BLL.BLL_FileLogs.WriteMainLogs(String.Format("错误:客户端连接已失去... ,数据发往客户端>>{0}", client.Client.RemoteEndPoint));
  543. }
  544. sendStreamToClient.Dispose();
  545. fs.Dispose();
  546. localClient.Close();
  547. if (totalBytes > 0)
  548. {
  549. return true;
  550. }
  551. else
  552. {
  553. return false;
  554. }
  555. }
  556. else
  557. {
  558. return false;
  559. }
  560. }
  561. catch {
  562. return false;
  563. }
  564. }
  565. #endregion
  566. }*/
  567. }