我有record
type
名称,登录名,外部IP,标签和布尔值。我想通过UDP
将该信息发送到其他计算机,我希望将其恢复为相同记录类型的变量。
我已经知道如何使用Indy的UDPClient / UDPServer发送和接收简单的字符串。
但是如何发送记录数据?
我还希望,如果可能的话,将此数据传递给我的加密方法codeSSL(s,k)
,收到后,传递给decodeSSL(s,k)
,但如果您能回答我的第一个问题,我将非常满意,更重要的是。
答案 0 :(得分:3)
您应该使用序列化库。 您可以在此链接中找到一些Delphi (win32) serialization libraries。
有关不同序列化库之间的比较基准,请参阅New sample for JSON performance: mORMot vs SuperObject/XSuperObject/dwsJSON/DBXJSON。
这是一个使用SuperObject以通用方式序列化/反序列化记录的示例。
program TestSerializer;
{$APPTYPE CONSOLE}
uses SuperObject;
type
Serializer = record
class function Serialize<T>(data: T): String; static;
class procedure Deserialize<T>(const jsonStr: String; var data: T); static;
end;
class procedure Serializer.Deserialize<T>(const jsonStr: String; var data: T);
var
ctx: TSuperRttiContext;
begin
ctx := TSuperRttiContext.Create;
try
data := ctx.AsType<T>(SO(jsonStr));
finally
ctx.Free;
end;
end;
class function Serializer.Serialize<T>(data: T): String;
var
ctx: TSuperRttiContext;
obj: ISuperObject;
begin
Result := '';
ctx := TSuperRttiContext.Create;
try
obj := ctx.AsJson<T>(data);
Result := obj.AsJson;
finally
ctx.Free;
end;
end;
type
TData = record
str: string;
int: Integer;
bool: Boolean;
flt: Double;
end;
var
data: TData;
jStr: String;
begin
data.str := 'Test';
data.int := 42;
data.bool := True;
data.flt := 3.14;
jStr := Serializer.Serialize<TData>(data);
WriteLn(jStr);
data.str := '';
Serializer.Deserialize<TData>(jStr,data);
ReadLn;
end.
如果您使用Indy,则有Send()
方法用于发送字符串数据。
您可以在此处找到一些字符串加密/解密示例:Delphi: simple string encryption。
答案 1 :(得分:3)
在发送方,您需要将记录数据序列化为扁平字节数组,可选择加密这些字节,然后发送它们。在接收端,您将读取字节,可选地解密它们,然后将它们序列化回记录。 TIdUDPClient
和TIdUDPServer
具有读取/写入TIdBytes
数据的方法,IdGlobal
单元具有操作TIdBytes
数据的功能。
例如:
发信人:
type
TMyRecord = record
Name: String;
Login: String;
ExternalIP: String;
Tags: String;
Flag: Boolean;
end;
procedure AppendStringToBuffer(var Bytes: TIdBytes; const S: String);
var
Tmp: TIdBytes;
Len: Byte;
begin
Tmp := ToBytes(S, enUTF8);
Len := Length(Tmp);
AppendByte(Bytes, Len);
AppendBytes(Bytes, Tmp);
end;
var
Rec: TMyRecord;
Buf: TIdBytes;
begin
Rec := ...;
AppendStringToBuffer(Buf, Rec.Name);
AppendStringToBuffer(Buf, Rec.Login);
AppendStringToBuffer(Buf, Rec.ExternalIP);
AppendStringToBuffer(Buf, Rec.Tags);
AppendByte(Buf, Ord(Rec.Flag));
// optionally encrypt the buffer...
MySocket.SendBuffer(TargetHost, TargetPort, Buf);
end;
接收器:
type
TMyRecord = record
Name: String;
Login: String;
ExternalIP: String;
Tags: String;
Flag: Boolean;
end;
function ReadStringFromBuffer(const Bytes: TIdBytes; var Index: Integer): String;
var
Len: Integer;
begin
Len := Bytes[Index];
Inc(Index);
if Len > 0 then
begin
Result := BytesToString(Bytes, Index, Len, enUTF8);
Inc(Index, Len);
end else
Result := '';
end;
var
Rec: TMyRecord;
Buf: TIdBytes;
BufLen, Index: Integer;
SenderIP: String;
SenderPort: TIdPort;
begin
SetLength(Buf, 1025);
BufLen := MySocket.ReceiveBuffer(Buf, SenderIP, SenderPort);
if Buf <= 0 then Exit;
// optionally decrypt the buffer...
Index := 0;
Rec.Name := ReadStringFromBuffer(Buf, Index);
Rec.Login := ReadStringFromBuffer(Buf, Index);
Rec.ExternalIP := ReadStringFromBuffer(Buf, Index);
Rec.Tags := ReadStringFromBuffer(Buf, Index);
Rec.Flag := Buf[Index] <> $00;
...
end;