Sending Record Data Structure in TCP C/S Application

Could someone give me a complete example of
sending the following record structure back and forth between Server & client utilizing the TServerSocket & TClientSocket components.

Type
 
 TOperationType = (ctAdd, ctDelete, ctModify);
 
 TMyRecord
  StringField: String;
  BoolField: Boolean;
  IntegerField: Integer;
  FloatField: Real;
  DateField: TDateTime;
  MemoFiled: TStrings;
  OperationField: TCustomType;
 end;

I will use the OperationField to determine what to do with the record on the appropriate side (Server/Client).

Shane
LVL 11
shaneholmesAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
ITugayConnect With a Mentor Commented:
Hi shaneholmes,

it seems you have to create a stream and write all fields of your record one by one:

procedure TForm1.SendRecord(T: TMyRecord);
var
  S: TMemoryStream;
  W: TWriter;
begin
  S := TMemoryStream.Create;

  // create helper object to make your life easy
  W := TWriter.Create(S, 1024);

  // preserve space in stream for total stream size
  W.WriteInteger(0);

  // write record to the stream
  W.WriteString(T.StringField);
  W.WriteBoolean(T.BoolField);
  W.WriteDate(T.DateField);
  //...
  T.MemoFiled.SaveToStream(S);
  W.WriteInteger(Integer(T.OperationField));

  // set amount of bytes to send
  // this value will be used in server part
  S.Seek(0, soFromBeginning);
  W.WriteInteger(S.Size);

  try
    if not ClientSocket1.Socket.SendStream(S) then
      raise Exception.Create('error while sending data');
  finally
    // be sure that temporary objects are freed
    W.Free;
    S.Free;
  end;
end;


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  S: TMemoryStream;
  R: TReader;
  N: Integer;
begin

  // T: TMyRecord;

  S := TMemoryStream.Create;
  R := TReader.Create(S, 1024);

  // get amount of bytes to read
  Socket.ReceiveBuf(N, SizeOf(Integer));
  // wet stream size
  S.SetSize(N-SizeOf(Integer));
  // read data from socket
  Socket.ReceiveBuf(S.Memory^, S.Size);

  // read fields to record
  T.StringField := R.ReadString;
  T.BoolField := R.ReadBoolean;
  T.DateField := R.ReadDate;
  //...
  T.MemoFiled.LoadFromStream(S);
  T.OperationField := TOperationType(R.ReadInteger);

  R.Free;
  S.Free;
end;

------
Igor
0
 
DragonSlayerCommented:
You could try this:

var
  MyRecord: TMyRecord;
begin
  // do something with MyRecord, fill it with data, etc
  MyServerSocket.SendBuf(MyRecord, SizeOf(TMyRecord));
end;

for the server socket, write a handler for OnClientRead and use ReceiveBuf to retrieve the record. Similarly, for the client socket, write a handler for OnRead



DragonSlayer.
0
 
shaneholmesAuthor Commented:
Great Job ITugay, I can work with this!

Thanks!

Shane
0
All Courses

From novice to tech pro — start learning today.