TcpClient.cs 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using System.IO;
  7. using System.Runtime.Serialization;
  8. using System.Runtime.Serialization.Formatters.Binary;
  9. using HPSocketCS.Extended;
  10. using System.Threading;
  11. using System.Drawing;
  12. namespace HPSocketCS
  13. {
  14. public class TcpClientEvent
  15. {
  16. public delegate HandleResult OnPrepareConnectEventHandler(TcpClient sender, uint socket);
  17. public delegate HandleResult OnConnectEventHandler(TcpClient sender);
  18. public delegate HandleResult OnSendEventHandler(TcpClient sender, byte[] bytes);
  19. public delegate HandleResult OnReceiveEventHandler(TcpClient sender, byte[] bytes);
  20. public delegate HandleResult OnCloseEventHandler(TcpClient sender, SocketOperation enOperation, int errorCode);
  21. }
  22. public class TcpClient
  23. {
  24. protected IntPtr _pClient = IntPtr.Zero;
  25. protected IntPtr pClient
  26. {
  27. get
  28. {
  29. return _pClient;
  30. }
  31. set
  32. {
  33. _pClient = value;
  34. }
  35. }
  36. protected IntPtr pListener = IntPtr.Zero;
  37. protected bool IsCreate = false;
  38. /****************************************************/
  39. /// <summary>
  40. /// 准备连接了事件
  41. /// </summary>
  42. public event TcpClientEvent.OnPrepareConnectEventHandler OnPrepareConnect;
  43. /// <summary>
  44. /// 连接事件
  45. /// </summary>
  46. public event TcpClientEvent.OnConnectEventHandler OnConnect;
  47. /// <summary>
  48. /// 数据发送事件
  49. /// </summary>
  50. public event TcpClientEvent.OnSendEventHandler OnSend;
  51. /// <summary>
  52. /// 数据到达事件
  53. /// </summary>
  54. public event TcpClientEvent.OnReceiveEventHandler OnReceive;
  55. /// <summary>
  56. /// 连接关闭事件
  57. /// </summary>
  58. public event TcpClientEvent.OnCloseEventHandler OnClose;
  59. public TcpClient()
  60. {
  61. CreateListener();
  62. }
  63. ~TcpClient()
  64. {
  65. Destroy();
  66. }
  67. /// <summary>
  68. /// 创建socket监听&服务组件
  69. /// </summary>
  70. /// <returns></returns>
  71. protected virtual bool CreateListener()
  72. {
  73. if (IsCreate == true || pListener != IntPtr.Zero || pClient != IntPtr.Zero)
  74. {
  75. return false;
  76. }
  77. pListener = Sdk.Create_HP_TcpClientListener();
  78. if (pListener == IntPtr.Zero)
  79. {
  80. return false;
  81. }
  82. pClient = Sdk.Create_HP_TcpClient(pListener);
  83. if (pClient == IntPtr.Zero)
  84. {
  85. return false;
  86. }
  87. IsCreate = true;
  88. return true;
  89. }
  90. /// <summary>
  91. /// 终止服务并释放资源
  92. /// </summary>
  93. public virtual void Destroy()
  94. {
  95. Stop();
  96. if (pClient != IntPtr.Zero)
  97. {
  98. Sdk.Destroy_HP_TcpClient(pClient);
  99. pClient = IntPtr.Zero;
  100. }
  101. if (pListener != IntPtr.Zero)
  102. {
  103. Sdk.Destroy_HP_TcpClientListener(pListener);
  104. pListener = IntPtr.Zero;
  105. }
  106. IsCreate = false;
  107. }
  108. #region 2017-02-26 修改
  109. string hp_address="";
  110. ushort hp_port=0;
  111. bool hp_async = false;
  112. string hp_bindAddress = "";
  113. protected bool connected;
  114. protected Exception exception;
  115. bool BeginConnected = false;
  116. /// <summary>
  117. /// 启动通讯组件并连接到服务器
  118. /// <param name="_timeout_milliseconds">使用者可以设置毫秒级的等待超时时间 (1000=1second)</param>
  119. /// </summary>
  120. /// <returns></returns>
  121. public bool Connetion(int _timeout_milliseconds=2500)
  122. {
  123. if (String.IsNullOrEmpty(hp_address))
  124. {
  125. return false;
  126. //throw new Exception("address is null");
  127. }
  128. else if (hp_port == 0)
  129. {
  130. return false;
  131. //throw new Exception("port is zero");
  132. }
  133. if (IsStarted)
  134. {
  135. return false;
  136. }
  137. connected = false;
  138. exception = null;
  139. Thread thread = new Thread(new ThreadStart(BeginConnect));
  140. thread.IsBackground = true; // 作为后台线程处理
  141. // 不会占用机器太长的时间
  142. thread.Start();
  143. // 等待如下的时间
  144. thread.Join(_timeout_milliseconds);
  145. if (connected)
  146. {
  147. // 如果成功就返回TcpClient对象
  148. thread.Abort();
  149. return BeginConnected;
  150. }
  151. if (exception != null)
  152. {
  153. // 如果失败就抛出错误
  154. thread.Abort();
  155. return BeginConnected;
  156. }
  157. else
  158. {
  159. // 同样地抛出错误
  160. thread.Abort();
  161. return BeginConnected;
  162. }
  163. }
  164. protected void BeginConnect()
  165. {
  166. try
  167. {
  168. BeginConnected = false;
  169. this.SetCallback();
  170. if (hp_bindAddress.Trim().Length > 1)
  171. {
  172. BeginConnected= Sdk.HP_Client_StartWithBindAddress(pClient, hp_address, hp_port, hp_async, hp_bindAddress);
  173. }
  174. else
  175. {
  176. BeginConnected= Sdk.HP_Client_Start(pClient, hp_address, hp_port, hp_async);
  177. }
  178. // 标记成功,返回调用者
  179. connected = true;
  180. }
  181. catch (Exception ex)
  182. {
  183. // 标记失败
  184. exception = ex;
  185. BeginConnected = false;
  186. }
  187. }
  188. #endregion
  189. /// <summary>
  190. /// 启动通讯组件并连接到服务器
  191. /// </summary>
  192. /// <param name="address">远程地址</param>
  193. /// <param name="port">远程端口</param>
  194. /// <param name="async">是否异步</param>
  195. /// <returns></returns>
  196. public bool Connetion(string address, ushort port, bool async = false)
  197. {
  198. if (string.IsNullOrEmpty(address) == true)
  199. {
  200. throw new Exception("address is null");
  201. }
  202. else if (port == 0)
  203. {
  204. throw new Exception("port is zero");
  205. }
  206. if (IsStarted == true)
  207. {
  208. return false;
  209. }
  210. hp_address = address;
  211. hp_port = port;
  212. hp_async = async;
  213. this.SetCallback();
  214. return Sdk.HP_Client_Start(pClient, address, port, async);
  215. }
  216. /// <summary>
  217. /// 启动通讯组件并连接到服务器
  218. /// </summary>
  219. /// <param name="address">远程地址</param>
  220. /// <param name="port">远程端口</param>
  221. /// <param name="bindAddress">本地绑定到哪个ip?,多ip下可以选择绑定到指定ip</param>
  222. /// <param name="async">是否异步</param>
  223. /// <returns></returns>
  224. public bool Connetion(string address, ushort port, string bindAddress, bool async = false)
  225. {
  226. if (string.IsNullOrEmpty(address) == true)
  227. {
  228. throw new Exception("address is null");
  229. }
  230. else if (port == 0)
  231. {
  232. throw new Exception("port is zero");
  233. }
  234. if (IsStarted == true)
  235. {
  236. return false;
  237. }
  238. hp_address = address;
  239. hp_port = port;
  240. hp_async = async;
  241. hp_bindAddress = bindAddress;
  242. this.SetCallback();
  243. return Sdk.HP_Client_StartWithBindAddress(pClient, address, port, async, bindAddress);
  244. }
  245. /// <summary>
  246. /// 停止通讯组件
  247. /// </summary>
  248. /// <returns></returns>
  249. public bool Stop()
  250. {
  251. if (IsStarted == false)
  252. {
  253. return false;
  254. }
  255. return Sdk.HP_Client_Stop(pClient);
  256. }
  257. /// <summary>
  258. /// 发送数据
  259. /// </summary>
  260. /// <param name="connId"></param>
  261. /// <param name="bytes"></param>
  262. /// <param name="size"></param>
  263. /// <returns></returns>
  264. public bool Send(byte[] bytes, int size)
  265. {
  266. return Sdk.HP_Client_Send(pClient, bytes, size);
  267. }
  268. /// <summary>
  269. /// 发送数据
  270. /// </summary>
  271. /// <param name="connId"></param>
  272. /// <param name="bufferPtr"></param>
  273. /// <param name="size"></param>
  274. /// <returns></returns>
  275. public bool Send(IntPtr bufferPtr, int size)
  276. {
  277. return Sdk.HP_Client_Send(pClient, bufferPtr, size);
  278. }
  279. /// <summary>
  280. /// 发送数据
  281. /// </summary>
  282. /// <param name="connId"></param>
  283. /// <param name="bufferPtr"></param>
  284. /// <param name="size"></param>
  285. /// <returns></returns>
  286. public bool Send<T>(T obj)
  287. {
  288. byte[] buffer = StructureToByte<T>(obj);
  289. return Send(buffer, buffer.Length);
  290. }
  291. /// <summary>
  292. /// 序列化对象后发送数据,序列化对象所属类必须标记[Serializable]
  293. /// </summary>
  294. /// <param name="connId"></param>
  295. /// <param name="bufferPtr"></param>
  296. /// <param name="size"></param>
  297. /// <returns></returns>
  298. public bool SendBySerializable(object obj)
  299. {
  300. byte[] buffer = ObjectToBytes(obj);
  301. return Send(buffer, buffer.Length);
  302. }
  303. /// <summary>
  304. /// 发送数据
  305. /// </summary>
  306. /// <param name="connId"></param>
  307. /// <param name="bytes"></param>
  308. /// <param name="offset">针对bytes的偏移</param>
  309. /// <param name="size">发多大</param>
  310. /// <returns></returns>
  311. public bool Send(byte[] bytes, int offset, int size)
  312. {
  313. return Sdk.HP_Client_SendPart(pClient, bytes, size, offset);
  314. }
  315. /// <summary>
  316. /// 发送数据
  317. /// </summary>
  318. /// <param name="connId"></param>
  319. /// <param name="bufferPtr"></param>
  320. /// <param name="offset">针对bufferPtr的偏移</param>
  321. /// <param name="size">发多大</param>
  322. /// <returns></returns>
  323. public bool Send(IntPtr bufferPtr, int offset, int size)
  324. {
  325. return Sdk.HP_Client_SendPart(pClient, bufferPtr, size, offset);
  326. }
  327. /// <summary>
  328. /// 发送多组数据
  329. /// 向指定连接发送多组数据
  330. /// TCP - 顺序发送所有数据包
  331. /// </summary>
  332. /// <param name="connId">连接 ID</param>
  333. /// <param name="pBuffers">发送缓冲区数组</param>
  334. /// <param name="iCount">发送缓冲区数目</param>
  335. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  336. public bool SendPackets(WSABUF[] buffers, int count)
  337. {
  338. return Sdk.HP_Client_SendPackets(pClient, buffers, count);
  339. }
  340. /// <summary>
  341. /// 发送多组数据
  342. /// 向指定连接发送多组数据
  343. /// TCP - 顺序发送所有数据包
  344. /// </summary>
  345. /// <param name="connId">连接 ID</param>
  346. /// <param name="pBuffers">发送缓冲区数组</param>
  347. /// <param name="iCount">发送缓冲区数目</param>
  348. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  349. public bool SendPackets<T>(T[] objects)
  350. {
  351. bool ret = false;
  352. WSABUF[] buffer = new WSABUF[objects.Length];
  353. IntPtr[] ptrs = new IntPtr[buffer.Length];
  354. try
  355. {
  356. for (int i = 0; i < objects.Length; i++)
  357. {
  358. buffer[i].Length = Marshal.SizeOf(typeof(T));
  359. ptrs[i] = Marshal.AllocHGlobal(buffer[i].Length);
  360. Marshal.StructureToPtr(objects[i], ptrs[i], true);
  361. buffer[i].Buffer = ptrs[i];
  362. }
  363. ret = SendPackets(buffer, buffer.Length);
  364. }
  365. catch (Exception ex)
  366. {
  367. throw ex;
  368. }
  369. finally
  370. {
  371. for (int i = 0; i < ptrs.Length; i++)
  372. {
  373. if (ptrs[i] != IntPtr.Zero)
  374. {
  375. Marshal.FreeHGlobal(ptrs[i]);
  376. }
  377. }
  378. }
  379. return ret;
  380. }
  381. /// <summary>
  382. /// 名称:发送小文件
  383. /// 描述:向指定连接发送 4096 KB 以下的小文件
  384. /// </summary>
  385. /// <param name="filePath">文件路径</param>
  386. /// <param name="head">头部附加数据</param>
  387. /// <param name="tail">尾部附加数据</param>
  388. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  389. public bool SendSmallFile(string filePath, ref WSABUF head, ref WSABUF tail)
  390. {
  391. return Sdk.HP_TcpClient_SendSmallFile(pClient, filePath, ref head, ref tail);
  392. }
  393. /// <summary>
  394. /// 名称:发送小文件
  395. /// 描述:向指定连接发送 4096 KB 以下的小文件
  396. /// </summary>
  397. /// <param name="filePath">文件路径</param>
  398. /// <param name="head">头部附加数据,可以为null</param>
  399. /// <param name="tail">尾部附加数据,可以为null</param>
  400. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  401. public bool SendSmallFile(string filePath, byte[] head, byte[] tail)
  402. {
  403. IntPtr pHead = IntPtr.Zero;
  404. IntPtr pTail = IntPtr.Zero;
  405. WSABUF wsaHead = new WSABUF() { Length = 0, Buffer = pHead };
  406. WSABUF wsatail = new WSABUF() { Length = 0, Buffer = pTail };
  407. if (head != null)
  408. {
  409. wsaHead.Length = head.Length;
  410. wsaHead.Buffer = Marshal.UnsafeAddrOfPinnedArrayElement(head, 0);
  411. }
  412. if (tail != null)
  413. {
  414. wsatail.Length = tail.Length;
  415. wsatail.Buffer = Marshal.UnsafeAddrOfPinnedArrayElement(tail, 0);
  416. }
  417. return SendSmallFile(filePath, ref wsaHead, ref wsatail);
  418. }
  419. /// <summary>
  420. /// 名称:发送小文件
  421. /// 描述:向指定连接发送 4096 KB 以下的小文件
  422. /// </summary>
  423. /// <param name="filePath">文件路径</param>
  424. /// <param name="head">头部附加数据,可以为null</param>
  425. /// <param name="tail">尾部附加数据,可以为null</param>
  426. /// <returns>TRUE.成功,FALSE.失败,可通过 SYSGetLastError() 获取 Windows 错误代码</returns>
  427. public bool SendSmallFile<T1, T2>(string filePath, T1 head, T2 tail)
  428. {
  429. byte[] headBuffer = null;
  430. if (head != null)
  431. {
  432. headBuffer = StructureToByte<T1>(head);
  433. }
  434. byte[] tailBuffer = null;
  435. if (tail != null)
  436. {
  437. tailBuffer = StructureToByte<T2>(tail);
  438. }
  439. return SendSmallFile(filePath, headBuffer, tailBuffer);
  440. }
  441. /// <summary>
  442. /// 获取错误码
  443. /// </summary>
  444. public SocketError ErrorCode
  445. {
  446. get
  447. {
  448. return Sdk.HP_Client_GetLastError(pClient);
  449. }
  450. }
  451. /// <summary>
  452. /// 获取错误信息
  453. /// </summary>
  454. public string ErrorMessage
  455. {
  456. get
  457. {
  458. IntPtr ptr = Sdk.HP_Client_GetLastErrorDesc(pClient);
  459. string desc = Marshal.PtrToStringUni(ptr);
  460. return desc;
  461. }
  462. }
  463. /// <summary>
  464. /// </summary>
  465. /// <param name="connId"></param>
  466. /// <param name="length"></param>
  467. /// <returns></returns>
  468. public bool GetPendingDataLength(ref int length)
  469. {
  470. return Sdk.HP_Client_GetPendingDataLength(pClient, ref length);
  471. }
  472. /// <summary>
  473. /// 设置连接的附加数据
  474. /// </summary>
  475. /// <param name="connId"></param>
  476. /// <param name="obj">如果为null,则为释放设置的数据</param>
  477. /// <returns></returns>
  478. public void SetExtra(object obj)
  479. {
  480. // 释放附加数据
  481. IntPtr ptr = GetExtra();
  482. if (ptr != IntPtr.Zero)
  483. {
  484. Marshal.FreeHGlobal(ptr);
  485. ptr = IntPtr.Zero;
  486. }
  487. if (obj != null)
  488. {
  489. // 设置附加数据
  490. ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
  491. Marshal.StructureToPtr(obj, ptr, false);
  492. }
  493. Sdk.HP_Client_SetExtra(pClient, ptr);
  494. }
  495. /// <summary>
  496. /// 获取附加数据
  497. /// 如设置的是个结构体/类对象,可以用 Type objA = (Type)Marshal.PtrToStructure(ptr, typeof(Type)) 获取
  498. /// 其中Type是结构体/类名,ptr是该方法的传出值,在该方法返回为true的时候可用
  499. /// </summary>
  500. /// <param name="connId"></param>
  501. /// <param name="ptr"></param>
  502. /// <returns></returns>
  503. public IntPtr GetExtra()
  504. {
  505. return Sdk.HP_Client_GetExtra(pClient);
  506. }
  507. /// <summary>
  508. /// 获取监听socket的地址信息
  509. /// </summary>
  510. /// <param name="ip"></param>
  511. /// <param name="ipLength"></param>
  512. /// <param name="port"></param>
  513. /// <returns></returns>
  514. public bool GetListenAddress(ref string ip, ref ushort port)
  515. {
  516. int ipLength = 40;
  517. StringBuilder sb = new StringBuilder(ipLength);
  518. bool ret = Sdk.HP_Client_GetLocalAddress(pClient, sb, ref ipLength, ref port);
  519. if (ret == true)
  520. {
  521. ip = sb.ToString();
  522. }
  523. return ret;
  524. }
  525. /// <summary>
  526. /// 是否启动
  527. /// </summary>
  528. public bool IsStarted
  529. {
  530. get
  531. {
  532. if (pClient == IntPtr.Zero)
  533. {
  534. return false;
  535. }
  536. return Sdk.HP_Client_HasStarted(pClient);
  537. }
  538. }
  539. /// <summary>
  540. /// 状态
  541. /// </summary>
  542. public ServiceState State
  543. {
  544. get
  545. {
  546. return Sdk.HP_Client_GetState(pClient);
  547. }
  548. }
  549. /// <summary>
  550. /// 获取该组件对象的连接Id
  551. /// </summary>
  552. public IntPtr ConnectionId
  553. {
  554. get
  555. {
  556. return Sdk.HP_Client_GetConnectionID(pClient);
  557. }
  558. }
  559. ///////////////////////////////////////////////////////////////////////////////////////
  560. /// <summary>
  561. /// 读取或设置内存块缓存池大小(通常设置为 -> PUSH 模型:5 - 10;PULL 模型:10 - 20 )
  562. /// </summary>
  563. public uint FreeBufferPoolSize
  564. {
  565. get
  566. {
  567. return Sdk.HP_Client_GetFreeBufferPoolSize(pClient);
  568. }
  569. set
  570. {
  571. Sdk.HP_Client_SetFreeBufferPoolSize(pClient, value);
  572. }
  573. }
  574. /// <summary>
  575. /// 读取或设置内存块缓存池回收阀值(通常设置为内存块缓存池大小的 3 倍)
  576. /// </summary>
  577. public uint FreeBufferPoolHold
  578. {
  579. get
  580. {
  581. return Sdk.HP_Client_GetFreeBufferPoolHold(pClient);
  582. }
  583. set
  584. {
  585. Sdk.HP_Client_SetFreeBufferPoolHold(pClient, value);
  586. }
  587. }
  588. ///////////////////////////////////////////////////////////////////////////////////////
  589. /// <summary>
  590. /// 读取或设置通信数据缓冲区大小(根据平均通信数据包大小调整设置,通常设置为:(N * 1024) - sizeof(TBufferObj))
  591. /// </summary>
  592. public uint SocketBufferSize
  593. {
  594. get
  595. {
  596. return Sdk.HP_TcpClient_GetSocketBufferSize(pClient);
  597. }
  598. set
  599. {
  600. Sdk.HP_TcpClient_SetSocketBufferSize(pClient, value);
  601. }
  602. }
  603. /// <summary>
  604. /// 读取或设置心跳包间隔(毫秒,0 则不发送心跳包)
  605. /// </summary>
  606. public uint KeepAliveTime
  607. {
  608. get
  609. {
  610. return Sdk.HP_TcpClient_GetKeepAliveTime(pClient);
  611. }
  612. set
  613. {
  614. Sdk.HP_TcpClient_SetKeepAliveTime(pClient, value);
  615. }
  616. }
  617. /// <summary>
  618. /// 读取或设置心跳确认包检测间隔(毫秒,0 不发送心跳包,如果超过若干次 [默认:WinXP 5 次, Win7 10 次] 检测不到心跳确认包则认为已断线)
  619. /// </summary>
  620. public uint KeepAliveInterval
  621. {
  622. get
  623. {
  624. return Sdk.HP_TcpClient_GetKeepAliveInterval(pClient);
  625. }
  626. set
  627. {
  628. Sdk.HP_TcpClient_SetKeepAliveInterval(pClient, value);
  629. }
  630. }
  631. /// <summary>
  632. /// 根据错误码返回错误信息
  633. /// </summary>
  634. /// <param name="code"></param>
  635. /// <returns></returns>
  636. public string GetSocketErrorDesc(SocketError code)
  637. {
  638. IntPtr ptr = Sdk.HP_GetSocketErrorDesc(code);
  639. string desc = Marshal.PtrToStringUni(ptr);
  640. return desc;
  641. }
  642. ///////////////////////////////////////////////////////////////////////////////////////
  643. Sdk.OnPrepareConnect _OnPrepareConnect = null;
  644. Sdk.OnConnect _OnConnect = null;
  645. Sdk.OnReceive _OnReceive = null;
  646. Sdk.OnSend _OnSend = null;
  647. Sdk.OnClose _OnClose = null;
  648. /// <summary>
  649. /// 设置回调函数
  650. /// </summary>
  651. protected virtual void SetCallback()
  652. {
  653. // 设置 Socket 监听器回调函数
  654. _OnPrepareConnect = new Sdk.OnPrepareConnect(SDK_OnPrepareConnect);
  655. _OnConnect = new Sdk.OnConnect(SDK_OnConnect);
  656. _OnSend = new Sdk.OnSend(SDK_OnSend);
  657. _OnReceive = new Sdk.OnReceive(SDK_OnReceive);
  658. _OnClose = new Sdk.OnClose(SDK_OnClose);
  659. Sdk.HP_Set_FN_Client_OnPrepareConnect(pListener, _OnPrepareConnect);
  660. Sdk.HP_Set_FN_Client_OnConnect(pListener, _OnConnect);
  661. Sdk.HP_Set_FN_Client_OnSend(pListener, _OnSend);
  662. Sdk.HP_Set_FN_Client_OnReceive(pListener, _OnReceive);
  663. Sdk.HP_Set_FN_Client_OnClose(pListener, _OnClose);
  664. }
  665. protected HandleResult SDK_OnPrepareConnect(IntPtr pClient, uint socket)
  666. {
  667. if (OnPrepareConnect != null)
  668. {
  669. return OnPrepareConnect(this, socket);
  670. }
  671. return HandleResult.Ignore;
  672. }
  673. protected HandleResult SDK_OnConnect(IntPtr pClient)
  674. {
  675. if (OnConnect != null)
  676. {
  677. return OnConnect(this);
  678. }
  679. return HandleResult.Ignore;
  680. }
  681. protected HandleResult SDK_OnSend(IntPtr pClient, IntPtr pData, int length)
  682. {
  683. if (OnSend != null)
  684. {
  685. byte[] bytes = new byte[length];
  686. Marshal.Copy(pData, bytes, 0, length);
  687. return OnSend(this, bytes);
  688. }
  689. return HandleResult.Ignore;
  690. }
  691. protected HandleResult SDK_OnReceive(IntPtr pClient, IntPtr pData, int length)
  692. {
  693. if (OnReceive != null)
  694. {
  695. byte[] bytes = new byte[length];
  696. Marshal.Copy(pData, bytes, 0, length);
  697. return OnReceive(this, bytes);
  698. }
  699. return HandleResult.Ignore;
  700. }
  701. protected HandleResult SDK_OnClose(IntPtr pClient, SocketOperation enOperation, int errorCode)
  702. {
  703. if (OnClose != null)
  704. {
  705. return OnClose(this, enOperation, errorCode);
  706. }
  707. return HandleResult.Ignore;
  708. }
  709. ///////////////////////////////////////////////////////////////////////////
  710. /// <summary>
  711. /// 获取系统返回的错误码
  712. /// </summary>
  713. public int SYSGetLastError()
  714. {
  715. return Sdk.SYS_GetLastError();
  716. }
  717. /// <summary>
  718. /// 调用系统的 ::WSAGetLastError() 方法获取通信错误代码
  719. /// </summary>
  720. public int SYSWSAGetLastError()
  721. {
  722. return Sdk.SYS_WSAGetLastError();
  723. }
  724. /// <summary>
  725. /// 调用系统的 setsockopt()
  726. /// </summary>
  727. /// <param name="sock"></param>
  728. /// <param name="level"></param>
  729. /// <param name="name"></param>
  730. /// <param name="val"></param>
  731. /// <param name="len"></param>
  732. /// <returns></returns>
  733. ///
  734. public int SYS_SetSocketOption(IntPtr sock, int level, int name, IntPtr val, int len)
  735. {
  736. return Sdk.SYS_SetSocketOption(sock, level, name, val, len);
  737. }
  738. /// <summary>
  739. /// 调用系统的 getsockopt()
  740. /// </summary>
  741. /// <param name="sock"></param>
  742. /// <param name="level"></param>
  743. /// <param name="name"></param>
  744. /// <param name="val"></param>
  745. /// <param name="len"></param>
  746. /// <returns></returns>
  747. ///
  748. public int SYSGetSocketOption(IntPtr sock, int level, int name, IntPtr val, ref int len)
  749. {
  750. return Sdk.SYS_GetSocketOption(sock, level, name, val, ref len);
  751. }
  752. /// <summary>
  753. /// 调用系统的 ioctlsocket()
  754. /// </summary>
  755. /// <param name="sock"></param>
  756. /// <param name="cmd"></param>
  757. /// <param name="arg"></param>
  758. /// <returns></returns>
  759. ///
  760. public int SYSIoctlSocket(IntPtr sock, long cmd, IntPtr arg)
  761. {
  762. return Sdk.SYS_IoctlSocket(sock, cmd, arg);
  763. }
  764. /// <summary>
  765. /// 调用系统的 ::WSAIoctl()
  766. /// </summary>
  767. /// <param name="sock"></param>
  768. /// <param name="dwIoControlCode"></param>
  769. /// <param name="lpvInBuffer"></param>
  770. /// <param name="cbInBuffer"></param>
  771. /// <param name="lpvOutBuffer"></param>
  772. /// <param name="cbOutBuffer"></param>
  773. /// <param name="lpcbBytesReturned"></param>
  774. /// <returns></returns>
  775. public int SYS_WSAIoctl(IntPtr sock, uint dwIoControlCode, IntPtr lpvInBuffer, uint cbInBuffer,
  776. IntPtr lpvOutBuffer, uint cbOutBuffer, uint lpcbBytesReturned)
  777. {
  778. return Sdk.SYS_WSAIoctl(sock, dwIoControlCode, lpvInBuffer, cbInBuffer,
  779. lpvOutBuffer, cbOutBuffer, lpcbBytesReturned);
  780. }
  781. /// <summary>
  782. /// 由结构体转换为byte数组
  783. /// </summary>
  784. public byte[] StructureToByte<T>(T structure)
  785. {
  786. int size = Marshal.SizeOf(typeof(T));
  787. byte[] buffer = new byte[size];
  788. IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
  789. try
  790. {
  791. Marshal.StructureToPtr(structure, bufferIntPtr, true);
  792. Marshal.Copy(bufferIntPtr, buffer, 0, size);
  793. }
  794. finally
  795. {
  796. Marshal.FreeHGlobal(bufferIntPtr);
  797. }
  798. return buffer;
  799. }
  800. /// <summary>
  801. /// 由byte数组转换为结构体
  802. /// </summary>
  803. public T ByteToStructure<T>(byte[] dataBuffer)
  804. {
  805. object structure = null;
  806. int size = Marshal.SizeOf(typeof(T));
  807. IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
  808. try
  809. {
  810. Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
  811. structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
  812. }
  813. finally
  814. {
  815. Marshal.FreeHGlobal(allocIntPtr);
  816. }
  817. return (T)structure;
  818. }
  819. /// <summary>
  820. /// 对象序列化成byte[]
  821. /// </summary>
  822. /// <param name="obj"></param>
  823. /// <returns></returns>
  824. public byte[] ObjectToBytes(object obj)
  825. {
  826. using (MemoryStream ms = new MemoryStream())
  827. {
  828. IFormatter formatter = new BinaryFormatter();
  829. formatter.Serialize(ms, obj);
  830. return ms.GetBuffer();
  831. }
  832. }
  833. /// <summary>
  834. /// byte[]序列化成对象
  835. /// </summary>
  836. /// <param name="Bytes"></param>
  837. /// <returns></returns>
  838. public object BytesToObject(byte[] bytes)
  839. {
  840. using (MemoryStream ms = new MemoryStream(bytes))
  841. {
  842. IFormatter formatter = new BinaryFormatter();
  843. return formatter.Deserialize(ms);
  844. }
  845. }
  846. /// <summary>
  847. /// byte[]转结构体
  848. /// </summary>
  849. /// <typeparam name="T"></typeparam>
  850. /// <param name="bytes"></param>
  851. /// <returns></returns>
  852. public T BytesToStruct<T>(byte[] bytes)
  853. {
  854. Type strcutType = typeof(T);
  855. int size = Marshal.SizeOf(strcutType);
  856. IntPtr buffer = Marshal.AllocHGlobal(size);
  857. try
  858. {
  859. Marshal.Copy(bytes, 0, buffer, size);
  860. return (T)Marshal.PtrToStructure(buffer, strcutType);
  861. }
  862. finally
  863. {
  864. Marshal.FreeHGlobal(buffer);
  865. }
  866. }
  867. #region 扩展方法
  868. CommonLibrary _CCommonLibrary = new CommonLibrary();
  869. /// <summary>
  870. /// 客户端扩展处理类
  871. /// </summary>
  872. public CommonLibrary CCommonLibrary
  873. {
  874. get { return _CCommonLibrary; }
  875. }
  876. /// <summary>
  877. /// 获取数据包最大长度
  878. /// </summary>
  879. /// <param name="pClient"></param>
  880. /// <returns></returns>
  881. public int GetMaxPackSize(IntPtr pClient)
  882. {
  883. return Convert.ToInt32(Sdk.HP_TcpPackClient_GetMaxPackSize(pClient));
  884. }
  885. #region 发送数据
  886. /// <summary>
  887. /// 自动拆包并发送
  888. /// </summary>
  889. /// <param name="bytes">要发送的数据</param>
  890. /// <param name="generateId">本次发送数据时的唯一ID</param>
  891. /// <returns></returns>
  892. public bool AutoUnpackingAndSend(byte[] bytes, Int64 generateId, DataType dType, TransferRequestCommand requestCommand, DelegateExecuteThreadStart callbackFun = null)
  893. {
  894. bool retbl = false;
  895. // 获取附加数据
  896. IntPtr clientPtr = this.GetExtra();
  897. ReceiveCacheBuffer cBuffer = new ReceiveCacheBuffer(generateId);
  898. cBuffer.CallbackFunction = callbackFun;
  899. this._CCommonLibrary.AddCacheBufferToList(generateId, cBuffer);
  900. TcpHeadInfo appendifo = CommonLibrary.GetProtocolHeader(this.ConnectionId, clientPtr, dType, requestCommand, generateId);
  901. int sendMaxPackSize = GetMaxPackSize(this.pClient);
  902. System.IO.BufferedStream sendMsstream = CommonLibrary.AutoUnpackingAndAddPkgHeader(bytes, appendifo, new TcpTailInfo(), sendMaxPackSize);
  903. try
  904. {
  905. int bytesRead = 0;
  906. long totalBytes = 0;
  907. do
  908. {
  909. byte[] sendFileBytes = null;
  910. if (sendMsstream.Length - totalBytes > sendMaxPackSize)
  911. {
  912. sendFileBytes = new byte[sendMaxPackSize];
  913. }
  914. else
  915. {
  916. sendFileBytes = new byte[Convert.ToInt32(sendMsstream.Length - totalBytes)];
  917. }
  918. bytesRead = sendMsstream.Read(sendFileBytes, 0, sendFileBytes.Length);
  919. if (bytesRead > 0)
  920. {
  921. totalBytes += bytesRead;
  922. // 发送
  923. if (this.Send(sendFileBytes, sendFileBytes.Length))
  924. {
  925. retbl = true;
  926. }
  927. else
  928. {
  929. retbl = false;
  930. break;
  931. }
  932. System.Threading.Thread.Sleep(1);
  933. }
  934. Array.Clear(sendFileBytes, 0, sendFileBytes.Length);
  935. System.GC.Collect();
  936. } while (bytesRead > 0);
  937. }
  938. catch { }
  939. finally
  940. {
  941. sendMsstream.Close();
  942. sendMsstream.Dispose();
  943. sendMsstream = null;
  944. }
  945. /* List<byte[]> sendPakByteList = CommonLibrary.AutoUnpackingAndAddPkgHeader(bytes, appendifo,new TcpTailInfo(), GetMaxPackSize(this.pClient));
  946. foreach (byte[] byteData in sendPakByteList)
  947. {
  948. // 发送
  949. if (this.Send(byteData, byteData.Length))
  950. {
  951. retbl = true;
  952. }
  953. else
  954. {
  955. retbl = false;
  956. break;
  957. }
  958. // System.Threading.Thread.Sleep(1);
  959. }
  960. sendPakByteList.Clear();
  961. sendPakByteList = null;*/
  962. System.GC.Collect();
  963. return retbl;
  964. }
  965. /// <summary>
  966. /// 自动拆包发送并返回结果
  967. /// </summary>
  968. /// <param name="bytes">要发送的数据</param>
  969. /// <param name="dType">发送的数据类型</param>
  970. /// <param name="requestCommand">请求命令</param>
  971. /// <returns></returns>
  972. public System.IO.MemoryStream AutoUnpackingSendAndReturnResult(byte[] bytes, DataType dType, TransferRequestCommand requestCommand, int millisecondsTimeout = 1000*90)
  973. {
  974. Int64 generateId = CommonLibrary.GenerateId();
  975. if (AutoUnpackingAndSend(bytes, generateId, dType, requestCommand))
  976. {
  977. return GetReceiveBytes(generateId, millisecondsTimeout);
  978. }
  979. return null;
  980. }
  981. /// <summary>
  982. /// 获取收到来至服务器端的数据 小于 Sdk.PacketBufferSize 数据接收
  983. /// </summary>
  984. /// <param name="generateId"></param>
  985. /// <param name="millisecondsTimeout"> 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。</param>
  986. /// <returns></returns>
  987. System.IO.MemoryStream GetReceiveBytes(Int64 generateId, int millisecondsTimeout = 1000*90)
  988. {
  989. System.IO.MemoryStream retBytes = new MemoryStream();
  990. try
  991. {
  992. ReceiveCacheBuffer recBuffer = this.CCommonLibrary.GetReceiveCacheBuffer(generateId);
  993. if (recBuffer != null)
  994. {
  995. recBuffer.MEvent.WaitOne(millisecondsTimeout);
  996. recBuffer.DataBuffer.WriteTo(retBytes);
  997. }
  998. }
  999. catch { }
  1000. finally
  1001. {
  1002. _CCommonLibrary.RemoveServerToClientByteList(generateId);
  1003. }
  1004. if (retBytes.Length > 0)
  1005. {
  1006. retBytes.Position = 0;
  1007. return retBytes;
  1008. }
  1009. else {
  1010. retBytes.Close();
  1011. retBytes.Dispose();
  1012. retBytes = null;
  1013. return null;
  1014. }
  1015. }
  1016. /// <summary>
  1017. /// 回调函数
  1018. /// </summary>
  1019. /// <param name="b"></param>
  1020. void WaitThreadFunc(object b)
  1021. {
  1022. ParameterObject pobj = (ParameterObject)b;
  1023. Int64 generateId = CommonLibrary.GenerateId();
  1024. try
  1025. {
  1026. if (AutoUnpackingAndSend(pobj.SendBytes, generateId, pobj.DType,pobj.RequestCommand, pobj.CallbackFun))
  1027. {
  1028. ReceiveCacheBuffer recBuffer = this.CCommonLibrary.GetReceiveCacheBuffer(generateId);
  1029. if (recBuffer != null)
  1030. {
  1031. recBuffer.MEvent.WaitOne(1000 * 90);
  1032. }
  1033. }
  1034. }
  1035. catch { }
  1036. finally
  1037. {
  1038. _CCommonLibrary.RemoveServerToClientByteList(generateId);
  1039. }
  1040. }
  1041. /// <summary>
  1042. /// 自动拆包发送并回调指定函数
  1043. /// </summary>
  1044. /// <param name="bytes"></param>
  1045. /// <param name="dType"></param>
  1046. /// <param name="requestCommand">请求命令</param>
  1047. /// <param name="dethStart"></param>
  1048. public void AutoUnpackingSendAndWaitCallback(byte[] bytes, DataType dType, TransferRequestCommand requestCommand, DelegateExecuteThreadStart callbackFun)
  1049. {
  1050. ParameterObject pobj = new ParameterObject();
  1051. pobj.CallbackFun = callbackFun;
  1052. pobj.DType = dType;
  1053. pobj.RequestCommand = requestCommand;
  1054. pobj.SendBytes = bytes;
  1055. ThreadPool.QueueUserWorkItem(new WaitCallback(WaitThreadFunc), pobj);
  1056. }
  1057. #endregion
  1058. #region 上传下载文件
  1059. #region 上传
  1060. /// <summary>
  1061. /// 上传图片
  1062. /// </summary>
  1063. /// <param name="img"></param>
  1064. /// <param name="toServerFileName"></param>
  1065. /// <param name="backgroundWorker"></param>
  1066. /// <returns></returns>
  1067. public bool UploadImage(Bitmap bmp, string toServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1068. {
  1069. bool retbl = false;
  1070. MemoryStream memoryMS = new MemoryStream();
  1071. try
  1072. {
  1073. bmp.Save(memoryMS, bmp.RawFormat);
  1074. byte[] sendFileBytes = memoryMS.ToArray();
  1075. if (sendFileBytes.Length > 0)
  1076. {
  1077. retbl = UploadFiles(sendFileBytes, sendFileBytes.Length, toServerFileName, backgroundWorker);
  1078. }
  1079. }
  1080. finally
  1081. {
  1082. memoryMS.Close();
  1083. memoryMS.Dispose();
  1084. memoryMS = null;
  1085. }
  1086. return retbl;
  1087. }
  1088. /// <summary>
  1089. /// 上传图片
  1090. /// </summary>
  1091. /// <param name="img"></param>
  1092. /// <param name="toServerFileName"></param>
  1093. /// <param name="backgroundWorker"></param>
  1094. /// <returns></returns>
  1095. public bool UploadImage(Image img, string toServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1096. {
  1097. bool retbl = false;
  1098. MemoryStream memoryMS = new MemoryStream();
  1099. try
  1100. {
  1101. img.Save(memoryMS, img.RawFormat);
  1102. memoryMS.Position = 0;
  1103. byte[] sendFileBytes = new byte[memoryMS.Length];
  1104. memoryMS.Read(sendFileBytes, 0, sendFileBytes.Length);
  1105. if (sendFileBytes.Length > 0)
  1106. {
  1107. retbl = UploadFiles(sendFileBytes, sendFileBytes.Length, toServerFileName, backgroundWorker);
  1108. }
  1109. }
  1110. finally {
  1111. memoryMS.Close();
  1112. memoryMS.Dispose();
  1113. memoryMS = null;
  1114. }
  1115. return retbl;
  1116. }
  1117. /// <summary>
  1118. /// 上传内存流
  1119. /// </summary>
  1120. /// <param name="memoryMS"></param>
  1121. /// <param name="toServerFileName"></param>
  1122. /// <param name="backgroundWorker"></param>
  1123. /// <returns></returns>
  1124. public bool UploadMemoryStream(MemoryStream memoryMS, string toServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1125. {
  1126. bool retbl = false;
  1127. try
  1128. {
  1129. if (memoryMS != null)
  1130. {
  1131. memoryMS.Position = 0;
  1132. byte[] sendFileBytes = new byte[memoryMS.Length];//memoryMS.GetBuffer();
  1133. memoryMS.Read(sendFileBytes, 0, sendFileBytes.Length);
  1134. if (sendFileBytes.Length > 0)
  1135. {
  1136. retbl = UploadFiles(sendFileBytes, sendFileBytes.Length, toServerFileName, backgroundWorker);
  1137. }
  1138. }
  1139. }
  1140. finally
  1141. {
  1142. memoryMS.Close();
  1143. memoryMS.Dispose();
  1144. memoryMS = null;
  1145. }
  1146. return retbl;
  1147. }
  1148. /// <summary>
  1149. /// 上传文件
  1150. /// </summary>
  1151. /// <param name="fileName"></param>
  1152. /// <param name="toServerFileName"></param>
  1153. /// <returns></returns>
  1154. public bool UploadFiles(string fileName, string toServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1155. {
  1156. bool retbl = false;
  1157. if (System.IO.File.Exists(fileName))
  1158. {
  1159. FileInfo fi = new FileInfo(fileName);
  1160. // 创建文件流
  1161. FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
  1162. System.IO.BufferedStream buffStream = new BufferedStream(fs, Sdk.PacketBufferSize*2);
  1163. try
  1164. {
  1165. int Subcontract = Sdk.PacketBufferSize;//分包大小
  1166. int bytesRead = 0;
  1167. long totalBytes = 0;
  1168. do
  1169. {
  1170. byte[] sendFileBytes = null;
  1171. if (fi.Length - totalBytes > Subcontract)
  1172. {
  1173. sendFileBytes = new byte[Subcontract];
  1174. }
  1175. else
  1176. {
  1177. sendFileBytes = new byte[fi.Length - totalBytes];
  1178. }
  1179. bytesRead = buffStream.Read(sendFileBytes, 0, sendFileBytes.Length);
  1180. if (bytesRead > 0)
  1181. {
  1182. bool IsSendComplete = false;
  1183. if (totalBytes + bytesRead >= fi.Length)
  1184. {
  1185. IsSendComplete = true;
  1186. }
  1187. if (totalBytes <= 0)
  1188. {
  1189. retbl = UploadFiles(sendFileBytes, fi.Length, toServerFileName, backgroundWorker, IsSendComplete: IsSendComplete);
  1190. }
  1191. else
  1192. {
  1193. retbl = UploadFiles(sendFileBytes, fi.Length, toServerFileName, backgroundWorker, FileMode.Append, totalBytes, IsSendComplete);
  1194. }
  1195. totalBytes += bytesRead;
  1196. }
  1197. Array.Clear(sendFileBytes, 0, sendFileBytes.Length);
  1198. System.GC.Collect();
  1199. } while (bytesRead > 0);
  1200. }
  1201. catch
  1202. {
  1203. }
  1204. finally {
  1205. buffStream.Flush();
  1206. buffStream.Close();
  1207. buffStream.Dispose();
  1208. buffStream = null;
  1209. fs.Close();
  1210. fs.Dispose();
  1211. fs = null;
  1212. }
  1213. }
  1214. return retbl;
  1215. }
  1216. /// <summary>
  1217. /// 上传文件字节数组
  1218. /// </summary>
  1219. /// <param name="sendFileBytes">要发送的字节数组</param>
  1220. /// <param name="sendTotalSize">要发送的文件总大小</param>
  1221. /// <param name="toServerFileName">要保存的文件名或路径</param>
  1222. /// <param name="backgroundWorker"></param>
  1223. /// <param name="mode">文件打开方式</param>
  1224. /// <param name="hasBeenSentSize">已发送大小</param>
  1225. /// <returns></returns>
  1226. public bool UploadFiles(byte[] sendFileBytes, long sendTotalSize, string toServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null, FileMode mode = FileMode.Create, long hasBeenSentSize = 0, bool IsSendComplete=true)
  1227. {
  1228. bool retbl = false;
  1229. /* if (sendFileBytes.Length > (Sdk.PacketBufferSize))
  1230. {
  1231. throw new Exception("上传文件大小不能超过" + (Sdk.PacketBufferSize / 1024 / 1024) + "MB。");
  1232. }
  1233. else */
  1234. if (sendFileBytes.Length == 0)
  1235. {
  1236. throw new Exception("上传文件大小不能为0。");
  1237. }
  1238. //总计数器
  1239. long sumCount = sendTotalSize;
  1240. //当前计数器
  1241. long currentCount = hasBeenSentSize;
  1242. Int64 generateId = CommonLibrary.GenerateId();
  1243. // 获取附加数据
  1244. IntPtr clientPtr = this.GetExtra();
  1245. // 头附加数据
  1246. TcpHeadInfo headinfo = CommonLibrary.GetProtocolHeader(this.ConnectionId, clientPtr, DataType.File, TransferRequestCommand.FileTransfer, generateId, true);
  1247. // 附加尾数据
  1248. TcpTailInfo tailinfo = new TcpTailInfo();
  1249. tailinfo.FileName = toServerFileName;
  1250. tailinfo.FileSize =sendTotalSize;
  1251. tailinfo.RequestType = (int)FileRequestType.Upload;
  1252. tailinfo.FileMode = (int)mode;
  1253. tailinfo.IsSendComplete = IsSendComplete;
  1254. int sendMaxPackSize = GetMaxPackSize(this.pClient);
  1255. System.IO.BufferedStream sendMsstream = CommonLibrary.AutoUnpackingAndAddPkgHeader(sendFileBytes, headinfo, tailinfo, sendMaxPackSize);
  1256. try
  1257. {
  1258. int bytesRead = 0;
  1259. long totalBytes = 0;
  1260. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "正在上传,请稍等...", backgroundWorker);
  1261. do
  1262. {
  1263. byte[] sendDataBytes = null;
  1264. if (sendMsstream.Length - totalBytes > sendMaxPackSize)
  1265. {
  1266. sendDataBytes = new byte[sendMaxPackSize];
  1267. }
  1268. else
  1269. {
  1270. sendDataBytes = new byte[Convert.ToInt32(sendMsstream.Length - totalBytes)];
  1271. }
  1272. bytesRead = sendMsstream.Read(sendDataBytes, 0, sendDataBytes.Length);
  1273. if (bytesRead > 0)
  1274. {
  1275. totalBytes += bytesRead;
  1276. currentCount += sendDataBytes.Length;
  1277. // 发送
  1278. if (this.Send(sendDataBytes, sendDataBytes.Length))
  1279. {
  1280. retbl = true;
  1281. }
  1282. else
  1283. {
  1284. retbl = false;
  1285. break;
  1286. }
  1287. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "正在上传,请稍等...", backgroundWorker);
  1288. System.Threading.Thread.Sleep(1);
  1289. }
  1290. Array.Clear(sendDataBytes, 0, sendDataBytes.Length);
  1291. System.GC.Collect();
  1292. } while (bytesRead > 0);
  1293. if (IsSendComplete)
  1294. {
  1295. currentCount = sumCount;
  1296. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "上传完成", backgroundWorker);
  1297. }
  1298. }
  1299. catch { }
  1300. finally
  1301. {
  1302. sendMsstream.Close();
  1303. sendMsstream.Dispose();
  1304. sendMsstream = null;
  1305. }
  1306. /* List<byte[]> sendPakByteList = CommonLibrary.AutoUnpackingAndAddPkgHeader(sendFileBytes, headinfo, tailinfo, GetMaxPackSize(this.pClient));
  1307. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "正在上传,请稍等...", backgroundWorker);
  1308. foreach (byte[] byteData in sendPakByteList)
  1309. {
  1310. currentCount += byteData.Length;
  1311. // 发送
  1312. if (this.Send(byteData, byteData.Length))
  1313. {
  1314. retbl = true;
  1315. }
  1316. else
  1317. {
  1318. retbl = false;
  1319. break;
  1320. }
  1321. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "正在上传,请稍等...", backgroundWorker);
  1322. System.Threading.Thread.Sleep(3);
  1323. }
  1324. if (currentCount >= sumCount)
  1325. {
  1326. CommonLibrary.SetBackgroundWorker(sumCount, currentCount, "上传完成", backgroundWorker);
  1327. }
  1328. sendPakByteList.Clear();
  1329. sendPakByteList = null;*/
  1330. System.GC.Collect();
  1331. return retbl;
  1332. }
  1333. #endregion
  1334. #region 下载
  1335. /// <summary>
  1336. /// 接收下载的文件数据包处理
  1337. /// </summary>
  1338. /// <param name="header"></param>
  1339. /// <param name="tail"></param>
  1340. /// <param name="recBuffer"></param>
  1341. /// <param name="recbytes"></param>
  1342. public bool ReceiveDownloadFile(TcpHeadInfo header, TcpTailInfo tail, ReceiveCacheBuffer recBuffer, byte[] recbytes)
  1343. {
  1344. try
  1345. {
  1346. if (recBuffer != null)
  1347. {
  1348. lock (recBuffer)
  1349. {
  1350. if (recBuffer.SaveToFileName.Trim().Length <= 0)
  1351. {
  1352. return recBuffer.ReceiveComplete(recbytes,tail.IsSendComplete);
  1353. }
  1354. else
  1355. {
  1356. string saveFilePath = recBuffer.SaveToFileName;
  1357. string saveDirPath = System.IO.Path.GetDirectoryName(saveFilePath);
  1358. if (!System.IO.Directory.Exists(saveDirPath))
  1359. {
  1360. try
  1361. {
  1362. System.IO.Directory.CreateDirectory(saveDirPath);
  1363. }
  1364. catch { }
  1365. }
  1366. FileMode fMode = (FileMode)tail.FileMode;
  1367. FileStream fs = new FileStream(saveFilePath, fMode, FileAccess.Write);
  1368. System.IO.BufferedStream buffStream = new BufferedStream(fs,Sdk.PacketBufferSize*2);
  1369. try
  1370. {
  1371. buffStream.Write(recbytes, 0, recbytes.Length);
  1372. buffStream.Flush();
  1373. // fs.Write(recbytes, 0, recbytes.Length);
  1374. }
  1375. finally
  1376. {
  1377. buffStream.Close();
  1378. buffStream.Dispose();
  1379. fs.Close();
  1380. fs.Dispose();
  1381. }
  1382. if (tail.IsSendComplete || recBuffer.Length >= tail.FileSize)
  1383. {
  1384. recBuffer.IsReceiveComplete = true;
  1385. recBuffer.MEvent.Set();
  1386. }
  1387. return true;
  1388. }
  1389. }
  1390. }
  1391. else {
  1392. return false;
  1393. }
  1394. }
  1395. catch {
  1396. return false;
  1397. }
  1398. }
  1399. /// <summary>
  1400. /// 发送下载请求
  1401. /// </summary>
  1402. /// <param name="generateId"></param>
  1403. /// <param name="comeFromServerFileName">要下载的文件名/路径</param>
  1404. /// <param name="saveToFileName">下载文件要保存的路径</param>
  1405. /// <param name="backgroundWorker">进程报告对象</param>
  1406. /// <returns></returns>
  1407. bool SenDownloadQequest(Int64 generateId, string comeFromServerFileName, string saveToFileName="", System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1408. {
  1409. bool retbl = false;
  1410. // 获取附加数据
  1411. IntPtr clientPtr = this.GetExtra();
  1412. // 头附加数据
  1413. TcpHeadInfo headinfo = CommonLibrary.GetProtocolHeader(this.ConnectionId, clientPtr, DataType.File, TransferRequestCommand.FileTransfer, generateId, true);
  1414. // 附加尾数据
  1415. TcpTailInfo tailinfo = new TcpTailInfo();
  1416. tailinfo.FileName = comeFromServerFileName;
  1417. tailinfo.FileSize = 0;
  1418. tailinfo.RequestType = (int)FileRequestType.Download;
  1419. tailinfo.FileMode = (int)FileMode.Create;
  1420. tailinfo.IsSendComplete = false;
  1421. ReceiveCacheBuffer cBuffer = new ReceiveCacheBuffer(generateId);
  1422. cBuffer.SaveToFileName=saveToFileName;
  1423. cBuffer.BackgroundWorker = backgroundWorker;
  1424. cBuffer.CallbackFunction = null;
  1425. this._CCommonLibrary.AddCacheBufferToList(generateId, cBuffer);
  1426. byte[] bytes = Encoding.UTF8.GetBytes("Download File");
  1427. int sendMaxPackSize = GetMaxPackSize(this.pClient);
  1428. // List<byte[]> sendPakByteList = CommonLibrary.AutoUnpackingAndAddPkgHeader(bytes, appendifo,new TcpTailInfo(), GetMaxPackSize(this.pServer));
  1429. System.IO.BufferedStream sendMsstream = CommonLibrary.AutoUnpackingAndAddPkgHeader(bytes, headinfo, tailinfo, sendMaxPackSize);
  1430. try
  1431. {
  1432. int bytesRead = 0;
  1433. long totalBytes = 0;
  1434. do
  1435. {
  1436. byte[] sendFileBytes = null;
  1437. if (sendMsstream.Length - totalBytes > sendMaxPackSize)
  1438. {
  1439. sendFileBytes = new byte[sendMaxPackSize];
  1440. }
  1441. else
  1442. {
  1443. sendFileBytes = new byte[Convert.ToInt32(sendMsstream.Length - totalBytes)];
  1444. }
  1445. bytesRead = sendMsstream.Read(sendFileBytes, 0, sendFileBytes.Length);
  1446. if (bytesRead > 0)
  1447. {
  1448. totalBytes += bytesRead;
  1449. // 发送
  1450. if (this.Send(sendFileBytes, sendFileBytes.Length))
  1451. {
  1452. retbl = true;
  1453. }
  1454. else
  1455. {
  1456. retbl = false;
  1457. break;
  1458. }
  1459. System.Threading.Thread.Sleep(1);
  1460. }
  1461. Array.Clear(sendFileBytes, 0, sendFileBytes.Length);
  1462. System.GC.Collect();
  1463. } while (bytesRead > 0);
  1464. }
  1465. catch { }
  1466. finally
  1467. {
  1468. sendMsstream.Close();
  1469. sendMsstream.Dispose();
  1470. sendMsstream = null;
  1471. }
  1472. /* List<byte[]> sendPakByteList = CommonLibrary.AutoUnpackingAndAddPkgHeader(bytes, headinfo, tailinfo, GetMaxPackSize(this.pClient));
  1473. foreach (byte[] byteData in sendPakByteList)
  1474. {
  1475. // 发送
  1476. if (this.Send(byteData, byteData.Length))
  1477. {
  1478. retbl = true;
  1479. }
  1480. else
  1481. {
  1482. retbl = false;
  1483. break;
  1484. }
  1485. System.Threading.Thread.Sleep(1);
  1486. }
  1487. sendPakByteList.Clear();
  1488. sendPakByteList = null;*/
  1489. System.GC.Collect();
  1490. return retbl;
  1491. }
  1492. /// <summary>
  1493. /// 下载到内存流
  1494. /// </summary>
  1495. /// <param name="comeFromServerFileName"></param>
  1496. /// <returns></returns>
  1497. public MemoryStream DownloadMemoryStream(string comeFromServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1498. {
  1499. Int64 generateId = CommonLibrary.GenerateId();
  1500. if (SenDownloadQequest(generateId, comeFromServerFileName, "", backgroundWorker))
  1501. {
  1502. return GetReceiveBytes(generateId, System.Threading.Timeout.Infinite);
  1503. }
  1504. return null;
  1505. }
  1506. /// <summary>
  1507. /// 下载文件并保存
  1508. /// </summary>
  1509. /// <param name="comeFromServerFileName">要下载的文件名/或路径</param>
  1510. /// <param name="saveToFileName">下载后的保存路径</param>
  1511. /// <param name="backgroundWorker"></param>
  1512. public bool DownloadFiles(string comeFromServerFileName,string saveToFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1513. {
  1514. Int64 generateId = CommonLibrary.GenerateId();
  1515. bool ret = false;
  1516. if (SenDownloadQequest(generateId, comeFromServerFileName, saveToFileName, backgroundWorker))
  1517. {
  1518. try
  1519. {
  1520. ReceiveCacheBuffer recBuffer = this.CCommonLibrary.GetReceiveCacheBuffer(generateId);
  1521. if (recBuffer != null)
  1522. {
  1523. recBuffer.MEvent.WaitOne(System.Threading.Timeout.Infinite);
  1524. ret= recBuffer.IsReceiveComplete;
  1525. }
  1526. }
  1527. catch { }
  1528. finally
  1529. {
  1530. _CCommonLibrary.RemoveServerToClientByteList(generateId);
  1531. }
  1532. }
  1533. return ret;
  1534. }
  1535. /// <summary>
  1536. /// 下载图片
  1537. /// </summary>
  1538. /// <param name="img"></param>
  1539. /// <param name="toServerFileName"></param>
  1540. /// <param name="backgroundWorker"></param>
  1541. /// <returns></returns>
  1542. public Bitmap DownloadBitmap(string comeFromServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1543. {
  1544. Bitmap bmp=null;
  1545. MemoryStream memoryMS = DownloadMemoryStream(comeFromServerFileName, backgroundWorker);
  1546. try
  1547. {
  1548. if (memoryMS != null && memoryMS.Length>0)
  1549. bmp = new Bitmap(memoryMS);
  1550. }
  1551. finally
  1552. {
  1553. if (memoryMS != null)
  1554. {
  1555. memoryMS.Close();
  1556. memoryMS.Dispose();
  1557. memoryMS = null;
  1558. }
  1559. }
  1560. return bmp;
  1561. }
  1562. /// <summary>
  1563. /// 下载图片
  1564. /// </summary>
  1565. /// <param name="img"></param>
  1566. /// <param name="toServerFileName"></param>
  1567. /// <param name="backgroundWorker"></param>
  1568. /// <returns></returns>
  1569. public Image DownloadImage(string comeFromServerFileName, System.ComponentModel.BackgroundWorker backgroundWorker = null)
  1570. {
  1571. return DownloadBitmap(comeFromServerFileName, backgroundWorker);
  1572. }
  1573. #endregion
  1574. #endregion
  1575. #endregion
  1576. }
  1577. /// <summary>
  1578. /// 参数对象
  1579. /// </summary>
  1580. public class ParameterObject {
  1581. public ParameterObject() {
  1582. }
  1583. DelegateExecuteThreadStart _callbackFun;
  1584. public DelegateExecuteThreadStart CallbackFun
  1585. {
  1586. get { return _callbackFun; }
  1587. set { _callbackFun = value; }
  1588. }
  1589. System.ComponentModel.BackgroundWorker backgroundWorker;
  1590. public System.ComponentModel.BackgroundWorker BackgroundWorker
  1591. {
  1592. get { return backgroundWorker; }
  1593. set { backgroundWorker = value; }
  1594. }
  1595. byte[] _sendBytes;
  1596. public byte[] SendBytes
  1597. {
  1598. get { return _sendBytes; }
  1599. set { _sendBytes = value; }
  1600. }
  1601. string fileName;
  1602. public string FileName
  1603. {
  1604. get { return fileName; }
  1605. set { fileName = value; }
  1606. }
  1607. DataType dType = DataType.Text;
  1608. public DataType DType
  1609. {
  1610. get { return dType; }
  1611. set { dType = value; }
  1612. }
  1613. TransferRequestCommand requestCommand = TransferRequestCommand.Message;
  1614. /// <summary>
  1615. /// 请求命令
  1616. /// </summary>
  1617. public TransferRequestCommand RequestCommand
  1618. {
  1619. get { return requestCommand; }
  1620. set { requestCommand = value; }
  1621. }
  1622. }
  1623. }