USMSSender.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. unit USMSSender;
  2. {$WARN SYMBOL_PLATFORM OFF}
  3. interface
  4. uses
  5. ComObj, ActiveX, RealICQInterfaces_TLB, StdVcl, Winsock2, RealICQSocket, Windows;
  6. type
  7. TSMSSender = class(TAutoObject, ISMSSender, IObjectSafety)
  8. private
  9. FObjectSafetyFlags: DWORD;
  10. FServerAddress: String;
  11. FServerPort: SYSINT;
  12. protected
  13. function Get_ServerAddress: PWideChar; safecall;
  14. procedure Set_ServerAddress(Value: OleVariant); safecall;
  15. function Get_ServerPort: SYSINT; safecall;
  16. procedure Set_ServerPort(Value: SYSINT); safecall;
  17. procedure SendSMS(PhoneID, P5PID: OleVariant; SendDateTime: TDateTime;
  18. Content: OleVariant); safecall;
  19. function GetInterfaceSafetyOptions(const IID: TIID; pdwSupportedOptions,
  20. pdwEnabledOptions: PDWORD): HResult; stdcall;
  21. function SetInterfaceSafetyOptions(const IID: TIID; dwOptionSetMask,
  22. dwEnabledOptions: DWORD): HResult; stdcall;
  23. end;
  24. implementation
  25. uses ComServ;
  26. //------------------------------------------------------------------------------
  27. function TSMSSender.GetInterfaceSafetyOptions(const IID: TIID;
  28. pdwSupportedOptions, pdwEnabledOptions: PDWORD): HResult;
  29. var
  30. Unk: IUnknown;
  31. begin
  32. if (pdwSupportedOptions = nil) or (pdwEnabledOptions = nil) then
  33. begin
  34. Result := E_POINTER;
  35. Exit;
  36. end;
  37. Result := QueryInterface(IID, Unk);
  38. if Result = S_OK then
  39. begin
  40. pdwSupportedOptions^ := INTERFACESAFE_FOR_UNTRUSTED_CALLER or
  41. INTERFACESAFE_FOR_UNTRUSTED_DATA;
  42. pdwEnabledOptions^ := FObjectSafetyFlags and
  43. (INTERFACESAFE_FOR_UNTRUSTED_CALLER or INTERFACESAFE_FOR_UNTRUSTED_DATA);
  44. end
  45. else begin
  46. pdwSupportedOptions^ := 0;
  47. pdwEnabledOptions^ := 0;
  48. end;
  49. end;
  50. //------------------------------------------------------------------------------
  51. function TSMSSender.SetInterfaceSafetyOptions(const IID: TIID;
  52. dwOptionSetMask, dwEnabledOptions: DWORD): HResult;
  53. var
  54. Unk: IUnknown;
  55. begin
  56. Result := QueryInterface(IID, Unk);
  57. if Result <> S_OK then Exit;
  58. FObjectSafetyFlags := dwEnabledOptions and dwOptionSetMask;
  59. end;
  60. function TSMSSender.Get_ServerAddress: PWideChar;
  61. begin
  62. end;
  63. procedure TSMSSender.Set_ServerAddress(Value: OleVariant);
  64. begin
  65. FServerAddress := Value;
  66. end;
  67. function TSMSSender.Get_ServerPort: SYSINT;
  68. begin
  69. end;
  70. procedure TSMSSender.Set_ServerPort(Value: SYSINT);
  71. begin
  72. FServerPort := Value;
  73. end;
  74. procedure TSMSSender.SendSMS(PhoneID, P5PID: OleVariant;
  75. SendDateTime: TDateTime; Content: OleVariant);
  76. var
  77. ServerSocket: TSocket;
  78. ServerAddr: TSockAddrIn;
  79. LastError: Integer;
  80. nIndex,
  81. ReturnValue: Integer;
  82. Buf: array[0..255] of Byte;
  83. FPhoneID, FP5PID, FContent: String;
  84. PhoneIDLength,
  85. P5PIDLength,
  86. ContentLength,
  87. BufferLength: SmallInt;
  88. SendBuffer: Array of Byte;
  89. begin
  90. ServerSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  91. if ServerSocket = INVALID_SOCKET then raise TSocketException.CreateFmt('创建套接字失败,错误代码:%d',[WSAGetLastError]);
  92. ServerAddr.sin_family:= AF_INET;
  93. ServerAddr.sin_port:= htons(FServerPort);
  94. ServerAddr.sin_addr.S_addr:= inet_addr(PChar(FServerAddress));
  95. connect(ServerSocket, @ServerAddr, SizeOf(ServerAddr));
  96. LastError := WSAGetLastError();
  97. if LastError <> 0 then
  98. begin
  99. closesocket(ServerSocket);
  100. raise TSocketException.CreateFmt('无法建立与服务器的连接,错误代码:%d', [LastError]);
  101. end;
  102. FPhoneID := PhoneID;
  103. FP5PID := P5PID;
  104. FContent := Content;
  105. PhoneIDLength := Length(FPhoneID);
  106. P5PIDLength := Length(FP5PID);
  107. ContentLength := Length(FContent);
  108. BufferLength := 14 + PhoneIDLength + P5PIDLength + ContentLength;
  109. SetLength(SendBuffer, BufferLength);
  110. nIndex := 0;
  111. //填充 (1)协议类型(0x98) 1byte
  112. SendBuffer[nIndex] := $98;
  113. Inc(nIndex, 1);
  114. //填充 (2)消息总长度 2byte
  115. CopyMemory(@SendBuffer[nIndex], @BufferLength, 2);
  116. Inc(nIndex, 2);
  117. //填充 (3)电话号码长度 1byte
  118. SendBuffer[nIndex] := Byte(PhoneIDLength);
  119. Inc(nIndex, 1);
  120. //填充 (4)电话号码 动态长度,由(4)指定
  121. CopyMemory(@SendBuffer[nIndex], PChar(FPhoneID), PhoneIDLength);
  122. Inc(nIndex, PhoneIDLength);
  123. //填充 (5)用户名长度 1byte
  124. SendBuffer[nIndex] := Byte(P5PIDLength);
  125. Inc(nIndex, 1);
  126. //填充 (6)用户名 动态长度,由(4)指定
  127. CopyMemory(@SendBuffer[nIndex], PChar(FP5PID), P5PIDLength);
  128. Inc(nIndex, P5PIDLength);
  129. //填充 (7)短消息长度长度 1byte
  130. SendBuffer[nIndex] := Byte(ContentLength);
  131. Inc(nIndex, 1);
  132. //填充 (8)短消息长度 动态长度,由(6)指定
  133. CopyMemory(@SendBuffer[nIndex], PChar(FContent), ContentLength);
  134. Inc(nIndex, ContentLength);
  135. //填充 (9)发送时间 8byte,64位浮点类型(double即TDateTime类型)
  136. CopyMemory(@SendBuffer[nIndex], @SendDateTime, 8);
  137. //Inc(nIndex, 8);
  138. ReturnValue := Send(ServerSocket, SendBuffer[0], BufferLength, 0);
  139. if ReturnValue <= 0 then
  140. begin
  141. closesocket(ServerSocket);
  142. raise TSocketException.Create('往服务器发送数据失败');
  143. end;
  144. FillChar(Buf, 256, #0);
  145. ReturnValue := Recv(ServerSocket, Buf, 1, 0);
  146. if ReturnValue <> 1 then
  147. begin
  148. closesocket(ServerSocket);
  149. raise TSocketException.Create('服务器上返回了错误的数据');
  150. end;
  151. closesocket(ServerSocket);
  152. if Buf[0] <> 0 then raise TSocketException.Create('数据发送失败');
  153. end;
  154. initialization
  155. TAutoObjectFactory.Create(ComServer, TSMSSender, Class_SMSSender,
  156. ciMultiInstance, tmApartment);
  157. end.