Delphi 如何读/写记录类型以通过udp发送它们?

Delphi 如何读/写记录类型以通过udp发送它们?,delphi,record,Delphi,Record,我有一个记录类型,包含名称、登录名、外部ip、标记和布尔值。我想通过UDP将该信息发送到其他计算机,在那里我想将其返回到同一记录类型的变量中 我已经知道如何使用Indy的UDPClient/UDPServer发送和接收简单字符串 但是如何发送记录数据呢 如果可能的话,我还想将此数据传递给我的加密方法codesl(s,k),收到后,传递给decodesl(s,k),但如果您能回答我的第一个问题,我会非常满意,这更重要。您应该使用序列化库。 您可以在此链接中找到一些 有关不同序列化库之间的比较基准,

我有一个
记录
类型
,包含名称、登录名、外部ip、标记和布尔值。我想通过
UDP
将该信息发送到其他计算机,在那里我想将其返回到同一记录类型的变量中

我已经知道如何使用Indy的UDPClient/UDPServer发送和接收简单字符串

但是如何发送记录数据呢


如果可能的话,我还想将此数据传递给我的加密方法
codesl(s,k)
,收到后,传递给
decodesl(s,k)
,但如果您能回答我的第一个问题,我会非常满意,这更重要。

您应该使用序列化库。 您可以在此链接中找到一些

有关不同序列化库之间的比较基准,请参阅

这是一个用于以通用方式序列化/反序列化记录的示例

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.
程序测试序列化程序;
{$APPTYPE控制台}
使用超对象;
类型
序列化程序=记录
类函数序列化(数据:T):字符串;静止的
类过程反序列化(const-jsonStr:String;var-data:T);静止的
结束;
类过程序列化程序。反序列化(const jsonStr:String;var data:T);
变量
ctx:Tsuperrti上下文;
开始
ctx:=tsupertitcontext.Create;
尝试
数据:=ctx.AsType(SO(jsonStr));
最后
免费;
结束;
结束;
类函数序列化器。序列化(数据:T):字符串;
变量
ctx:Tsuperrti上下文;
obj:ISuperObject;
开始
结果:='';
ctx:=tsupertitcontext.Create;
尝试
obj:=ctx.AsJson(数据);
结果:=obj.AsJson;
最后
免费;
结束;
结束;
类型
TData=记录
str:字符串;
int:整数;
布尔:布尔;
外语:双;
结束;
变量
数据:TData;
jStr:String;
开始
data.str:=“测试”;
data.int:=42;
data.bool:=真;
data.flt:=3.14;
jStr:=Serializer.Serialize(数据);
WriteLn(jStr);
data.str:='';
反序列化(jStr,数据);
ReadLn;
结束。
如果您使用的是Indy,那么就有一个发送字符串数据的
Send()
方法


您可以在这里找到一些字符串加密/解密的示例:。

在发送端,您需要将记录数据序列化为一个平面字节数组,可以选择加密这些字节,然后发送它们。在接收端,您可以读取字节,有选择地对它们进行解密,然后将它们序列化回记录中
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;
类型
TMyRecord=记录
名称:字符串;
登录:字符串;
ExternalIP:字符串;
标签:字符串;
标志:布尔;
结束;
函数ReadStringFromBuffer(常量字节:TIdBytes;变量索引:Integer):字符串;
变量
Len:整数;
开始
Len:=字节[索引];
公司(指数),;
如果Len>0,则
开始
结果:=BytesToString(字节、索引、Len、enUTF8);
公司(索引,Len);
结束其他
结果:='';
结束;
变量
记录:TMyRecord;
Buf:TIdBytes;
BufLen,索引:整数;
SenderIP:String;
发送端口:TIdPort;
开始
设定长度(Buf,1025);
BufLen:=MySocket.ReceiveBuffer(Buf、SenderIP、SenderPort);

如果Buf使用许多序列化库中的一个进行序列化。例如超对象。