Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Jan : Re: TClientSocket write progress???

www.cryer.info
Managed Newsgroup Archive

Re: TClientSocket write progress???

Subject:Re: TClientSocket write progress???
Posted by:"Bo Berglund" (bo.berglu..@telia.com)
Date:Thu, 24 Jan 2008 07:35:42

On Wed, 23 Jan 2008 14:32:58 -0800, "Remy Lebeau \(TeamB\)"
<no.spam@no.spam.com> wrote:

>
>"Bo Berglund" <bo.berglund@telia.com> wrote in message
>news:qj9fp39rsferohbpkb958r9f28a2otejmd@4ax.com...
>
>> But when I send using SendText the complete string I am about to
>> send is "swallowed" in an instant and the sendtext call immediately
>> returns.
>
>The timing does not matter at all.  You passed a block of data to the
>socket.  You know how many bytes you passed in.  The socket returned the
>number of bytes it actually accepted.  So you have all the info you need to
>update your progress right then and there.

>> I only call this once for each block of data I send...
>> So there is no progress of blocks being sent to show.
>
>Yes there is.
>

Something is not right here...
I have written the send part of my program this way (the repeat loop
was put there only yesterday after reading your responses):

function TSSRemoteClient.SendTextData(Msg: string): boolean;
var
  TxLen: integer;
  Tel: string;
begin
  Result := false;
  try
    if FSocket.Socket.Connected then
    begin
      LogStd('Tx to ' + FSocket.Socket.RemoteAddress + ': ' + Msg);
      FPacketCount := 0;
      Tel := STX + Msg + ETX;
      repeat
        TxLen := FSocket.Socket.SendText(Tel);
        Delete(Tel, 1, TxLen);
      until Length(Tel) = 0;
      Result := true;
    end
    else
      LogErr('Disconnected from host, cannot send data');
  except
    on E: Exception do
      LogErr('Exception in SendTextData: ' + E.Message);
  end;
end;

Before this I just used
  FSocket.Socket.SendText(Tel);
and no repeat loop.

When sending a file I load it fully into memory, then make a hex
conversion of every single byte in the file body (blowing it up by x2)
to make the data ASCII. Then I tack on the STX and ETX chars and send
it off using this function.

I have not ever gotten a truncated file sent. And I have tested with
files more than several megabytes in size.
And I have also tested to see what happens in this area of the code
while stepping through. The SendText method always returns
*immediately* at the same time as network activity starts and
continues for a long time.

My code then goes on to wait for a response from the other side
telling me if the transfer succeeded or not (that the other side fully
retrieved the data until the ETX char).
This wait takes maybe 20 s for a large file and here is where I want
to have the progress info.
But your suggestion would mean having the progress go from 0 to 100%
instantaneously when the data are still only starting to being
transfered.

>> the string is about 7 Mb in size
>
>Why are you using strings to hold that much data?  You should be using byte
>arrays or streams instead.  In fact, you shouldn't be using SendText() for
>that much data anyway, because there is no way the socket can accept 7Mb of
>data at one time to begin with.  At the very least, you MUST keep track of
>SendText's return value so that you call SendText in a loop until all of the
>data has been accepted successfully.  I described that scenerio to you in my
>earlier reply, because you have to take the OnWrite event into account.
>There is no way around that in this situation.  Your data is too large not
>to.  So you may as well redesign how you are managing the data storage so
>you can send it more efficiently using SendBuf() and byte offsets.  Deleting
>characters from a string and obtaining substrings is going to be a
>performance bottleneck during the send of such large data.
>
>> This does not happen, the sendtext method always returns the
>> length of the string I am supplying to it...
>
>Not for 7Mb strings, it can't.  The socket's buffer is not that large.  It
>is around 8Kb by default.  But even for smaller strings, you still MUST take
>the return value and OnWrite events into account properly, or you risk
>corrupting your transmissions.  You are NEVER guaranteed that the socket
>will accept everything you give it in one go, or receive everything you tell
>it to in one go.  That is simply the nature of TCP programming in general.
>The sooner you learn that, the more solid and error-proof you will design
>your code to be.  I guarantee that you will hit up on this issue eventually.
>Every socket programmer does.

Very strange that I can put 7 Mb of data into a buffer that holds 8kb
without losing any data....
Because I don't.

Anyway, I put in the repeat loop on sending just in case...

Remember that my post was not about how to stop losing data, it was on
getting a transfer progress display while successfully sending the
data. As I said I have never once had a bad transfer and I test big
chunks of data on purpose to see what will happen.

We must be talking about different things, strange enough.


/BoB

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive