【发布时间】:2017-05-09 18:07:00
【问题描述】:
我在 Delphi 10.1 Berlin 中使用 FireMonkey 开发 Android 移动客户端应用程序,我在 Delphi 10.1 Berlin 中使用 VCL 开发 Windows 服务器应用程序。
在移动应用中,我使用TIdTCPClient发送以下记录:
PSampleReq = ^TSampleReq ;
TSampleReq = packed record
Value1: array [0..10] of Char;
Value2: array [0..59] of Char;
Value3: array [0..40] of Char;
Value4: Int64;
Value5: array [0..9] of Char;
Value6: array [0..9] of Char;
Value7: Integer;
end;
我已经用数据填充了数据包,并正在使用以下代码发送数据包:
FIdTCPClient.IOHandler.Write(RawToBytes(TSampleReq,SizeOf(TSampleReq)));
在服务器应用程序中读取数据时,我无法读取Value5、Value6 和Value7 字段。下面是读取数据的代码:
Move(tyTIDBytes[0], SampleReq, SizeOf(TSampleReq));
为了接收从客户端套接字发送的数据,我使用了 TIDTcpServer 并在 Execute 方法中处理了以下代码:
TServerRecord = packed record
PointerMessage : TIndyBytes;
ClientSocket : TIdTCPConnection;
end;
Var
ReceivedIDBytes: TServerRecord;
begin
if not AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
AContext.Connection.IOHandler.InputBuffer.ExtractToBytes(ReceivedIDBytes.PointerMessage.tyTIDBytes) ;
ReceivedIDBytes.ClientSocket := AContext.Connection;
MessageProcessorThread.ProcessMessageQueue.Enqueue(ReceivedIDBytes);
end;
在此之后我正在处理来自Queue的数据以及我在下面提到的处理方法:
var
InputRec: TServerRecord;
begin
InputRec := DBWorkerThread.DBWorkerQueue.Dequeue;
MessageHeaderPtr := @InputRec.PointerMessage.tyTIDBytes[0];
iHMMessageCode := StrToIntDef( Trim(MessageHeaderPtr^.MessageCode), UNKNOWN_MESSAGE_CODE);
case iHMMessageCode of
1001:
begin
Move(InputRec.PointerMessage.tyTIDBytes[0], SampleReq, SizeOf(TSampleReq));
end;
end;
在此我无法读取 Value5、Value6 和 Value7 字段。
通过下面的链接,我发现了一些优化技术以及如何正确处理数据包而不会丢失任何数据包。请帮我解决这个问题。
【问题讨论】:
-
您是否确认
sizeof(TSampleReq)在两个 应用程序中正好是276 字节?在调用Move()之前,您没有显示填充tyTIDBytes的实际 阅读代码。代码应该是这样的:var tyTIDBytes: TIdBytes; ... AContext.Connection.IOHandler.ReadBytes(tyTIDBytes, SizeOf(TSampleReq), False);而且仅供参考,Indy 有一个BytesToRaw()函数作为RawToBytes()的伴侣:BytesToRaw(tyTIDBytes, SampleReq, SizeOf(TSampleReq)); -
而且仅供参考,您没有使用other link 中描述的“优化技术”。该技术在发送实际数据之前发送数据大小。 Indy 等效项如下所示:
tyTIDBytes := RawToBytes(SampleReq, SizeOf(TSampleReq); FIdTCPClient.IOHandler.Write(Int32(Length(tyTIDBytes))); FIdTCPClient.IOHandler.Write(tyTIDBytes);...AContext.Connection.IOHandler.ReadBytes(tyTIDBytes, AContext.Connection.IOHandler.ReadInt32, False); BytesToRaw(tyTIDBytes, SampleReq, SizeOf(TSampleReq)); -
请edit您的问题显示您在连接两端使用的实际代码。您的发送代码和阅读代码之间显然不匹配。而且您没有回答我之前的问题:“您是否验证
sizeof(TSampleReq)在两个应用程序中正好是 276 字节?”。跨度> -
我在我的问题中添加了额外的信息,并且应该从服务器接收部分处理不同的记录,我也尝试了你的方法,但我仍然面临同样的问题。
-
你没有使用我描述的技术,甚至没有接近。您对
ExtractToBytes()的使用完全错误,是您问题的根源。我现在已经发布了答案。
标签: delphi firemonkey vcl delphi-10.1-berlin delphi-10.2-tokyo