🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.socket
Article #5263

Re: Client: ctNonBlocking -> Server: stThreadBlocking

#5263
From: Vladimir Stefanovic
Date: Mon, 27 Sep 2004 20:14
202 lines
6730 bytes
What can I say than thanks for the detailed explanation with
full source code included. I'll try this tomorrow cos I do not
have BCB on this machine.



Best regards,
Vladimir Stefanovic

Remy Lebeau (TeamB) <no.spam@no.spam.com> wrote in message
news:41586fe3$1@newsgroups.borland.com...
>
> "Vladimir Stefanovic" <spam@not.needed> wrote in message
> news:415856d5@newsgroups.borland.com...
>
> > How can I send data with TClientSocket
> > in ctNonBlocking to Server.
>
> The same way you send it with ctBlocking.  The only thing you have
to watch
> out for is that ctNonBlocking may not always be able to accept new
data
> because it may block the socket.  In that case, you have to check
the return
> value of SendBuf().  If it returns -1, you have to wait for the
socket's
> OnWrite event to be triggered before you can write data to the
socket again.
>
> > I have the sending code which only works when the mode
> > is ctBlocking. What can I do to modify the code to work
> > in ctNonBlocking mode?
>
> The easily way is to simply call Application->ProcessMessages()
inside your
> loop whenever SendBuf() returns -1 so that OnWrite can be processed.
This
> would essentially make the code act like blocking code..  -1 is
*NOT* an
> error for a non-blocking socket unless the OnError event is
triggered.
> Otherwise, -1 simply means that the socket would have been blocked,
but the
> socket is otherwise still valid.  For example (untested):
>
>     void __fastcall TcliForm::SendButtonClick(TObject *Sender)
>     {
>         if( (!ClientSocket->Active) ||
(!ClientSocket->Socket->Connected) )
>             return;
>
>         SendButtonClick->Enabled = false;
>
>         int NumberOfBytes = OutboxDataBuffer->Size;
>
>         bool bSent = SendData(&NumberOfBytes, sizeof(int));
>         if( bSent )
>             bSent = SendData(OutboxDataBuffer->Memory,
NumberOfBytes);
>
>         if( !bSent )
>             ShowMessage( "Error!" );
>
>         SendButtonClick->Enabled = true;
>     }
>
>     bool __fastcall TcliForm::SendData(void* Buffer, int BufSize)
>     {
>         LPBYTE pBuffer = (LPBYTE) pBuffer;
>         int TotalSent = 0;
>
>         try
>         {
>             while( TotalSent < BufSize )
>             {
>                 int NumberOfBytesSent =
> ClientSocket->Socket->SendBuf(&pBuffer[TotalSent],
BufSize-TotalSent);
>                 if( NumberOfBytes == -1 )
>                     Application->ProcessMessages();
>                 else
>                     TotalSent += NumberOfBytes;
>             }
>             return true;
>         }
>         catch(const Exception &)
>         {
>             return false;
>         }
>     }
>
>
> Otherwise, you will have to re-write the code to use a queing system
> instead, for example (untested):
>
>     #define APPWM_SEND_DATA    (WM_APP+100)
>
>     __fastcall TcliForm::TcliForm(TComponent* Owner)
>         : TForm(Owner)
>     {
>         OutboxDataBuffer = new TMemoryStream;
>     }
>
>     __fastcall TcliForm::~TcliForm()
>     {
>         delete OutboxDataBuffer;
>     }
>
>     void __fastcall TcliForm::SendButtonClick(TObject *Sender)
>     {
>         if( (!ClientSocket->Active) ||
(!ClientSocket->Socket->Connected) )
>             return;
>
>         TFileStream *FS = new
ileStream( ExtractFilePath( ParamStr(0) ) +
> "test.txt" );
>         try
>         {
>             int FileSize = FS->Size;
>             OutboxDataBuffer->Write(&FileSize, sizeof(int));
>             OutboxDataBuffer->CopyFrom(FS, FileSize);
>         }
>         __finally
>         {
>             delete FS;
>             if( OutboxDataBuffer->Size > 0 )
>                 PostMessage(Handle, APPWM_SEND_DATA, 0, 0);
>         }
>
>         SendButton->Enabled = false;
>     }
>
>     void __fastcall TcliForm::ClientSocketWrite(TObject* Sender,
> TCustomWinSocket* Socket)
>     {
>         if( OutboxDataBuffer->Size > 0 )
>             PostMessage(Handle, APPWM_SEND_DATA, 0, 0);
>     }
>
>     void __fastcall TcliForm::WndProc(TMessage &Message)
>     {
>         if( Message.Msg == APPWM_SEND_DATA )
>         {
>             int Size = OutboxDataBuffer->Size;
>
>             int NumberOfBytesSent =
SendData(OutboxDataBuffer->Memory,
> Size);
>             if( NumberOfBytesSent > 0 )
>             {
>                 if( NumberOfBytesSent == Size )
>                     OutboxDataBuffer->Clear();
>                 else
>                 {
>                     LPBYTE pSource =
 ((LPBYTE)OutboxDataBuffer->Memory) +
> NumberOfBytesSent );
>                     int NumberOfBytesLeft =
(Size-NumberOfBytesSent);
>
>                     ::MoveMemory(OutboxDataBuffer->Memory, pSource,
> NumberOfBytesLeft);
>                     OutboxDataBuffer->Size = NumberOfBytesLeft;
>                 }
>
>                 Size = OutboxDataBuffer->Size;
>             }
>
>             if( Size == 0 )
>                 SendButton->Enabled = true;
>         }
>         else
>             TForm::WndProc(Message);
>     }
>
>     int __fastcall TcliForm::SendData(void* Buffer, int BufSize)
>     {
>         LPBYTE pBuffer = (LPBYTE) pBuffer;
>         int TotalSent = 0;
>
>         try
>         {
>             while( TotalSent < BufSize )
>             {
>                 int NumberOfBytesSent =
> ClientSocket->Socket->SendBuf(&pBuffer[TotalSent],
BufSize-TotalSent);
>                 if( NumberOfBytes == -1 )
>                     break;
>                 TotalSent += NumberOfBytes;
>             }
>         }
>         catch(const Exception &) { }
>         return TotalSent;
>     }
>
>
> Gambit
>
>
Technical Details
Message-ID: <41587454@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!news.zanker.org!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <415856d5@newsgroups.borland.com> <41586fe3$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,b3058d6528d1daa1
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Vladimir Stefanovic" <spam@not.needed>
Newsgroups: borland.public.cppbuilder.internet.socket
References: <415856d5@newsgroups.borland.com> <41586fe3$1@newsgroups.borland.com>
Subject: Re: Client: ctNonBlocking -> Server: stThreadBlocking
Date: Mon, 27 Sep 2004 22:14:29 +0200
Lines: 204
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.00.2314.1300
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300
NNTP-Posting-Host: 213.137.116.181
Message-ID: <41587454@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1096315988 213.137.116.181 (27 Sep 2004 13:13:08 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!news.zanker.org!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail