We help IT Professionals succeed at work.

Send Record via Winsock

Torus
Torus asked
on
I have defined a record and want to transfer to a custom server using Delphi 5 built-in winsock VCL. The record
size is 5000 bytes or more. In local lan, it should be no problem. The server can receive the record completely in
triggering the ServerSocket1ClientRead event(TServerSocket) once time. However, if in the slow network, the ServerSocket1ClientRead event need triggering 2 or 3 times before I can get the complete record.(use receivebuf(TCustomWInSock) to get data)

In this situation, how can I know I get the data completely and concat the data getting in several time from the event so that I can assign back the data to my
defined record variable??  




Comment
Watch Question

One way is to add some special ID to identify the beginning and the end of your record... perhaps something like this:

type
  TMyRecord = packed record
    HeaderID: array [0 .. 1] of Char;
    // other structures
    TailID: array [0 .. 1] of Char;
  end;

set HeaderID and TailID to something unique, that won't exist as part of your normal data... e.g. HeaderID = '##' and TailID = '%%'

so in your ReceiveBuf, when you see that you have reached %% it is time to put the next byte(s) into a new record... and if you did not reach %% but you see ##, that means the previous record was corrupt and you need to re-transfer.
Commented:
Here's some pseudo-code for you:

//Define a global variable near the top of your unit to hold the data received:
buf: array[1..SizeOf(TMyBigRecord)] of byte;
//keep track of # of bytes received:
sofar: integer;

procedure OnConnectionEstablished(...);
begin
  sofar := 0;
end;

procedure OnDataAvailableEvent(...);
var
  brec: TMyBigRecord;
begin
  Socket.Read(buf[sofar+1],NumberOfBytesInSocket);
  inc(sofar,NumberOfBytesInSocket);
  if sofar >= SizeOf(TMyBigRecord) then
  begin
    Move(buf[1],brec,SizeOf(TMyBigRecord));
    sofar := 0;
    DoSomethingWithTheFullRecord(brec);
  end;  
end;

procedure DoSomethingWithTheFullRecord(bigrec: TMyBigRecord);
begin
  //do whateva u wanna do with it here
end;

Author

Commented:
rondi, the idea works. But your pseudo-code has problem.
The move statement doesn't work.
But I can still give you mark .

Commented:
Try using pointer addresses instead:
  Move(@buf[1],@brec,SizeOf(TMyBigRecord));