uStreamCoderSocket.pas 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. unit uStreamCoderSocket;
  2. interface
  3. uses
  4. uICoderSocket, Classes,
  5. SysUtils;
  6. type
  7. {$if CompilerVersion < 18}
  8. TBytes = array of Byte;
  9. {$IFEND}
  10. TStreamCoderSocket = class(TObject)
  11. private
  12. class function SendStream(pvSocket: ICoderSocket; pvStream: TStream): Integer;
  13. public
  14. /// <summary>
  15. /// 接收解码
  16. /// </summary>
  17. /// <returns> Boolean
  18. /// </returns>
  19. /// <param name="pvSocket"> (TClientSocket) </param>
  20. /// <param name="pvObject"> (TObject) </param>
  21. class function RecvObject(pvSocket: ICoderSocket; pvObject: TObject): Boolean;
  22. /// <summary>
  23. /// 编码发送
  24. /// </summary>
  25. /// <param name="pvSocket"> (TClientSocket) </param>
  26. /// <param name="pvDataObject"> (TObject) </param>
  27. class function SendObject(pvSocket: ICoderSocket; pvObject: TObject): Integer;
  28. end;
  29. function verifyData(const buf; len:Cardinal): Cardinal;
  30. implementation
  31. //PACK_FLAG + CRC_VALUE + STREAM_LEN + STREAM_DATA
  32. uses
  33. uByteTools;
  34. function verifyData(const buf; len: Cardinal): Cardinal;
  35. var
  36. i:Cardinal;
  37. p:PByte;
  38. begin
  39. i := 0;
  40. Result := 0;
  41. p := PByte(@buf);
  42. while i < len do
  43. begin
  44. Result := Result + p^;
  45. Inc(p);
  46. Inc(i);
  47. end;
  48. end;
  49. const
  50. PACK_FLAG = $D10;
  51. MAX_OBJECT_SIZE = 1024 * 1024 * 10; //最大对象大小 10M , 大于10M 则会认为错误的包。
  52. const
  53. BUF_BLOCK_SIZE = 1024 * 8;
  54. resourcestring
  55. strRecvException_ErrorFlag = '错误的包头数据,断开与服务器的连接';
  56. strRecvException_ErrorData = '错误的数据,断开与服务器的连接';
  57. strRecvException_VerifyErr = '错误的数据包,校验失败!';
  58. strSendException_TooBig = '数据包太大,请在业务层分拆发送,最大数据包[%d]!';
  59. strSendException_NotEqual = '发送Buffer错误指定发送%d,实际发送:%d';
  60. { TStreamCoderSocket }
  61. class function TStreamCoderSocket.RecvObject(pvSocket: ICoderSocket;
  62. pvObject: TObject): Boolean;
  63. var
  64. lvBytes:TBytes;
  65. lvReadL, lvTempL:Integer;
  66. lvPACK_FLAG:Word;
  67. lvDataLen: Integer;
  68. lvVerifyValue, lvVerifyDataValue:Cardinal;
  69. lvPByte:PByte;
  70. begin
  71. pvSocket.recvBuf(@lvPACK_FLAG, 2);
  72. if lvPACK_FLAG <> PACK_FLAG then
  73. begin
  74. pvSocket.closeSocket;
  75. //错误的包数据
  76. raise Exception.Create(strRecvException_ErrorFlag);
  77. end;
  78. //veri value
  79. pvSocket.recvBuf(@lvVerifyValue, SizeOf(lvVerifyValue));
  80. //headlen
  81. pvSocket.recvBuf(@lvReadL, SizeOf(lvReadL));
  82. lvDataLen := TByteTools.swap32(lvReadL);
  83. //文件头不能过大
  84. if lvDataLen > MAX_OBJECT_SIZE then
  85. begin
  86. //错误的包数据
  87. pvSocket.closeSocket;
  88. //错误的包数据
  89. raise Exception.Create(strRecvException_ErrorData);
  90. end;
  91. SetLength(lvBytes,lvDataLen);
  92. lvPByte := PByte(@lvBytes[0]);
  93. lvReadL := 0;
  94. while lvReadL < lvDataLen do
  95. begin
  96. lvTempL := pvSocket.recvBuf(lvPByte, lvDataLen - lvReadL);
  97. if lvTempL = -1 then
  98. begin
  99. RaiseLastOSError;
  100. end;
  101. Inc(lvPByte, lvTempL);
  102. lvReadL := lvReadL + lvTempL;
  103. end;
  104. {$IFDEF POSIX}
  105. lvVerifyDataValue := verifyData(lvBytes[0], lvDataLen);
  106. {$ELSE}
  107. lvVerifyDataValue := verifyData(lvBytes[0], lvDataLen);
  108. {$ENDIF}
  109. if lvVerifyDataValue <> lvVerifyValue then
  110. begin
  111. raise Exception.Create(strRecvException_VerifyErr);
  112. end;
  113. TStream(pvObject).Write(lvBytes[0], lvDataLen);
  114. Result := true;
  115. end;
  116. class function TStreamCoderSocket.SendObject(pvSocket: ICoderSocket; pvObject:
  117. TObject): Integer;
  118. var
  119. lvPACK_FLAG: WORD;
  120. lvDataLen, lvWriteIntValue: Integer;
  121. lvBuf: TBytes;
  122. lvStream:TMemoryStream;
  123. lvVerifyValue:Cardinal;
  124. begin
  125. lvPACK_FLAG := PACK_FLAG;
  126. lvStream := TMemoryStream.Create;
  127. try
  128. TStream(pvObject).Position := 0;
  129. if TStream(pvObject).Size > MAX_OBJECT_SIZE then
  130. begin
  131. raise Exception.CreateFmt(strSendException_TooBig, [MAX_OBJECT_SIZE]);
  132. end;
  133. //pack_flag
  134. lvStream.Write(lvPACK_FLAG, 2);
  135. //
  136. lvDataLen := TStream(pvObject).Size;
  137. // stream data
  138. SetLength(lvBuf, lvDataLen);
  139. TStream(pvObject).Read(lvBuf[0], lvDataLen);
  140. //veri value
  141. lvVerifyValue := verifyData(lvBuf[0], lvDataLen);
  142. lvStream.Write(lvVerifyValue, SizeOf(lvVerifyValue));
  143. lvWriteIntValue := TByteTools.swap32(lvDataLen);
  144. // stream len
  145. lvStream.Write(lvWriteIntValue, SizeOf(lvWriteIntValue));
  146. // send pack
  147. lvStream.write(lvBuf[0], lvDataLen);
  148. Result := SendStream(pvSocket, lvStream);
  149. finally
  150. lvStream.Free;
  151. end;
  152. end;
  153. class function TStreamCoderSocket.SendStream(pvSocket: ICoderSocket; pvStream:
  154. TStream): Integer;
  155. var
  156. lvBufBytes:array[0..BUF_BLOCK_SIZE-1] of byte;
  157. l, j, r, lvTotal:Integer;
  158. P:PByte;
  159. begin
  160. Result := 0;
  161. if pvStream = nil then Exit;
  162. if pvStream.Size = 0 then Exit;
  163. lvTotal :=0;
  164. pvStream.Position := 0;
  165. repeat
  166. //FillMemory(@lvBufBytes[0], SizeOf(lvBufBytes), 0);
  167. l := pvStream.Read(lvBufBytes[0], SizeOf(lvBufBytes));
  168. if (l > 0) then
  169. begin
  170. P := PByte(@lvBufBytes[0]);
  171. j := l;
  172. while j > 0 do
  173. begin
  174. r := pvSocket.sendBuf(P, j);
  175. if r = -1 then
  176. begin
  177. RaiseLastOSError;
  178. end;
  179. Inc(P, r);
  180. Dec(j, r);
  181. end;
  182. lvTotal := lvTotal + l;
  183. end else Break;
  184. until (l = 0);
  185. Result := lvTotal;
  186. end;
  187. end.