Jump to content
Lindawb

Just sent type OnDataAvailable

Recommended Posts

Hello,

I'm sending 2 types of data, one as data and other one as simple text message, now with help of good people I was able to get data as memorystream, but I can't get any string text

 

Client.Send(aBuff,Length(aBuff));  // works on OnDataAvailable

but

Client.SendStr('This is a string');  // doesn't work, like bad header

My question: is it possible to check the sent data(tbyes) or string, if winsocketdata process as data, if string just read it as string on same OnDataAvailable ?

 

Thank you

Share this post


Link to post

You've to create a protocol eg. a prefix that will say the following x bytes is a string or a binary data so the reciever can convert the received bytes back.

Share this post


Link to post

If you still sending your own packets, then strings need a header too, then converted to array of bytes just like the jpeg.

added a send/recv string to the packet client and server demo, so you can see one way to do this.

also generalized the server a bit, changed from q of jpeg to tPacketData which is DataType then array of bytes.

Updated server example to show simple method of determining incoming array data.

 

i tend to treat my strings as fixed arrays of bytes and those are in larger records of data.

don't typically just send one string.

i'll update the demo to show how to send record structures in a few days.

Share this post


Link to post

As we explained previously, you need to design a protocol with a header to explain what type of data you are sending and how much.  One well known such protocol is HTTP which ICS supports, and is much easier to use than designing your own.  

 

One standard in most protocols is that text is terminated with CRLF at the end of each command or line, which your SendStr does not do, but which can be useful to know that a complete line has arrived for processing and potentially to recognize that text is being sent, although binary files may potentially include CRLF. 

 

Angus

 

Share this post


Link to post

Thank you all of you,

Previously I did look all sockets demo, but I will check all demos to see how is done.

 

I assume you are saying to do something like this:

type
   TMyRec = record
     HeaderType: string;
     FirstName: string[40];
     LastName: string[40];

     Message: string;
   end;

 

Thanks again for your time

Share this post


Link to post

Your TMyRec would not work as a header since the String types point to memory and only the pointer would be sent, it needs fixed length elements and ideally Length: Integer at the start set to the actual length, so the application decoding it can handle changes in the record in the future.   

 

Angus

 

Share this post


Link to post

No more like..

TMyRec = packed record

  Header:TPacketHdr;

  FirstName: array[0..39] of byte;

  LastName:array[0..39] of byte;

  Message:array[0..499] of byte;

   end;

 

 

Share this post


Link to post

added this into the demo i did previously for you..

now you can send/recv a jpeg, a single string (can be as long as you wish) or a record structure.

Share this post


Link to post

Thank you so much,

 

I tried to use as below, but looks going nowhere.

 

procedure TForm1.Button3Click(Sender: TObject);
var
  defaultRec : TMyRec;
 result, mystr: string;
  aHdr:tPacketHdr;
begin


        FillPacketIdent(aHdr.Ident);
      aHdr.Command:=CMD_STR; //CMD_STR added to uPacketDefs


       mystr:= 'Hello Delphi Developers';

       aHdr.DataSize:=SizeOf(mystr[1]);
      // SetString(mystr, PAnsiChar(@defaultRec.FirstName[0]), Length(defaultRec.FirstName));

      //write to record
        SetLength(mystr, length(defaultRec.FirstName));
        Move(defaultRec.FirstName[0], mystr[1], Length(defaultRec.FirstName));

        ShowMessage(PwideChar(defaultRec.FirstName[0]));


      //  SetLength(result,  Length(defaultRec.FirstName));
      //  Move(defaultRec.FirstName[0], result[1], Length(result) * SizeOf(result[1]));

      // SetLength(S, Length(A));
      // Move(A[0], S[1], Length(S) * SizeOf(S[1]));

      //read the record
       SetString(result, pwidechar(@defaultRec.FirstName[0]), Length(defaultRec.FirstName));


       ShowMessage(result);


end;

 

 

Thank you

Share this post


Link to post

not usre how you got there, this is whats in the demo, i expanded the comments

 

procedure TMainFrm.SendString;

var
aHdr:tPacketHdr;
aStr:String;
aBytes:TBytes;
aBuff:TBytes;
begin
 
aStr:='Hello from client!!';//string could be sent into procedure
 
if Length(aStr)>0 then
begin
FillPacketIdent(aHdr.Ident);//fill our indent
aHdr.Command:=CMD_STR;//tell server its a string
aBytes:=TEncoding.ANSI.GetBytes(aStr);//encode string to array of bytes
SetLength(aBuff,SizeOf(tPacketHdr)+Length(aBytes));//make our transmission buffer big enough for header and string
aHdr.DataSize:=Length(aBytes);// size of string, always use length instead of size of on dynamic sizes
Move(aHdr,aBuff[0],SizeOf(tPacketHdr));// move the header into buffer
Move(aBytes[0],aBuff[SizeOf(tPacketHdr)],Length(aBytes));//move string into buffer just after header
PacketClntDm.cliSock.Send(aBuff,Length(aBuff));//send it off
SetLength(aBytes,0);
SetLength(aBuff,0);
end;
 
 
 
 

end;

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×