Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help creating a string buffer for Indy TCP Server/Client

Status
Not open for further replies.

djjd47130

Programmer
Nov 1, 2010
480
US
I'm using Indy 10 in Delphi XE2 to send 'parts' of an image (remote desktop) as-needed. Meaning, the Client will be sending, in bulk, small pieces of an image non-stop for the life of the socket (or as long as image sending is enabled). The amount of parts which are sent vary in size, and depends on activity on the client. I already have a way to only send certain parts of the screen.

To keep things smooth, I've decided to implement a single string buffer to append the data to, while another thread picks up that data and streams it through the socket. So the thread copies/deletes for example 255 characters from the beginning of the string at a time, and sends along what it copied.

Here's the packet format...

<LEFT><DELIM><TOP><DELIM><SIZE_OF_DATA><DELIM><DATA.......>
<DELIM> = Unique deliminator (global constant)
<LEFT> = Integer: Left position of image part
<TOP> = Integer: Top position of image part
<SIZE_OF_DATA> = Integer: String size of remainder data
<DATA> = String: Data of actual image

...and appending this string to the end of an "Out Buffer String". Another thread then reads from this string and sends chunks no larger than <SET_BUFFER_SIZE> (Setting for buffer size, default 255).

I stopped when I realized that maybe this isn't such a good idea to have an outgoing buffer. Shouldn't Indy already do this for me, and all I have to do is immediately send the packet string?

I already have a separate socket to accommodate for commands which turn this image streaming on or off. I just need to know what's the best recommended method to accommodate for this scenario? Should I use a buffer like this or should I just immediately send it? Would it make a difference for how Indy TIdTCPClient handles the large amounts of data? The client side of the socket does not care whether or not the packet got there, so I'm not worried about the server replying to anything the client sends. However it is important that what was sent is received, therefore I cannot use UDP.


JD Solutions
 

Optimize your packet size to be as close as possible to the MTU (eg 1500 bytes - IP overhead).
Don't use strings. TIdBytes or TMemorystream are better candidates in your scenario.

so in short, suppose you want to sent an image of 14kb
-> divide image into 10 Stream object(1,4kb per part) and put it a Queue.
-> a worker thread will process that queue and a new thread that sends the Stream object,
limit the number of threads to the number of physical cores, so implement pooling.
-> send metainfo first and then the actual data

something like:
TImageInfo = packed record
Id : TGuid;
Size : Integer;
Chunks : Integer;
Left : Integer;
Top : Integer;
end;
you can append first chunk after the info record.

TImageChunk = packed record
Id : TGuid;
Chunk : Integer;
Size : Integer;
Data : Array[0..1400] of Byte;
end;

streaming record is a nobrainer with Indy...

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top