🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: TServerSocket SendText Exception

#2410
From: Eric Patterson
Date: Tue, 25 Apr 2006 17:53
174 lines
7169 bytes
Wow.  That is some tricky stuff.  I always thought you used components to 
make life easy.  If that is the easy version, I would hate to see what that 
component actually does with the window's socket api.  Thanks for the full 
example.  I will see what happens.

Eric


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message 
news:444d14c5@newsgroups.borland.com...
>
> "Eric Patterson" <eric.patterson@bepco.com> wrote in message
> news:444cd08c$1@newsgroups.borland.com...
>
>> Do you think that the Invalid Pointer Exception is coming from
>> the client not being present?
>
> That is a possibility, if you are allowing messages to be processed while
> you are still looping through the connections.  When a client disconnects,
> the OnClientDisconnect event is triggered, and then the server posts a
> CM_DEFERFREE message back to itself.  When that message is processed, the
> client socket is freed immediately.  If you continue to access the socket
> after it has been freed, then your code has undefined behavior from that
> point on, and anything can happen.
>
>> The system I have setup should always have a client present; I
>> typically (and my test rig is setup this way) only have two client's
>> connected to the server application.  They both get the same messages
>> no matter what and they should never leave (or disconnect from the
>> server).
>
> You should not be relying on that behavior.  You are not allowing your 
> code
> to handle unforseen issues, such as network/power outages, transmission
> errors, etc.
>
>> Also you stated earlier that I can't keep doing a sendtext until I get
>> a ClientWrite Event after a -1 was returned from a SendText.
>
> Please re-read what I said.  What I actually said was that you have to 
> call
> WSAGetLastError() in order to find out why SendText() is returning -1. 
> The
> OnWrite event be triggered later on only when WSAGetLastError() returns
> WSAEWOULDBLOCK.  Any other value is an actual socket error and the socket
> can no longer be used and must be reconnected.
>
>> Now you are saying I have to do a SendText (pump the message queue)
>> so I know the state of the socket.
>
> Only for the specific code snippet that you showed, which would not work
> given the way you showed it.  You are now relying on a variable that 
> cannot
> be set without the OnWrite event being triggered, and it cannot be 
> triggered
> while you are still running a loop until the loop pumps the message queue 
> fo
> r pending messages.
>
> I strongly suggest that you go to http://www.deja.com and search through 
> the
> newsgroup archives.  I have posted sample code dealing with non-blocking
> sockets and the OnWrite event on several different occasions.  For 
> example,
> here is a more reliable way to deal with queuing outbound data:
>
>    void __fastcall TServer::ServerSocketClientConnect(TObject* Sender,
> TCustomWinSocket* Socket)
>    {
>        Socket->Data = new TMemoryStream;
>    }
>
>    void __fastcall TServer::ServerSocketClientDisconnect(TObject* Sender,
> TCustomWinSocket* Socket)
>    {
>        delete static_cast<TMemoryStream*>(Socket->Data);
>        Socket->Data = NULL;
>    }
>
>    void __fastcall TServer::ServerSocketClientWrite(TObject* Sender,
> TCustomWinSocket* Socket)
>    {
>        TMemoryStream *MS = static_cast<TMemoryStream*>(Socket->Data);
>        if( MS->Size > 0 )
>        {
>            MS->Position = 0
>
>            LPBYTE ptr = static_cast<LPBYTE>(MS->Memory);
>            int sent;
>
>            while( MS->Position < MS->Size )
>            {
>                sent = Socket->SendBuf(&ptr[MS->Position], MS->Size -
> MS->Position);
>                if( sent > 0 )
>                    MS->Seek(sent, soFromCurrent);
>                else
>                    break;
>            }
>
>            if( MS->Position > 0 )
>            {
>                int remaining = (MS->Size - MS->Position);
>                if( remaining > 0 )
>                {
>                    if( MS->Position > 0 )
>                    {
>                        Move(&ptr[MS->Position], MS->Memory, remaining);
>                        MS->Size = remaining;
>                    }
>                }
>                else
>                    MS->Clear();
>            }
>        }
>    }
>
>    void __fastcall TServer::SendBufferToSocket(TCustomWinSocket *Socket,
> void *Buffer, int BufSize)
>    {
>        TMemoryStream *MS = static_cast<TMemoryStream*>(Socket->Data);
>        LPBYTE ptr = static_cast<LPBYTE>(Buffer);
>
>        if( MS->Size == 0 )
>        {
>            int sent;
>
>            while( BufSize > 0 )
>            {
>                sent = Socket->SendBuf(ptr, BufSize);
>                if( sent > 0 )
>                {
>                    ptr += sent;
>                    BufSize -= sent;
>                    continue;
>                }
>
>                if( (sent == 0) || (WSAGetLastError() != WSAEWOULDBLOCK) )
>                    return;
>
>                break;
>            }
>
>            if( BufSize < 1 )
>                return;
>        }
>
>        MS->Seek(0, soFromEnd);
>        MS->WriteBuffer(ptr, BufSize);
>    }
>
>    void __fastcall TServer::SendTextToSocket(TCustomWinSocket *Socket,
> const AnsiString &S)
>    {
>        SendBufferToSocket(Socket, S.c_str(), S.Length());
>    }
>
>    void __fastcall TServer::SendMsg(const AnsiString &AMsg)
>    {
>        for(int ii = 0; ii < ServerSocket1->Socket->ActiveConnections; 
> ++ii)
>            SendTextToSocket(ServerSocket1->Socket->Connections[ii], AMsg +
> "\n");
>    }
>
>    void __fastcall TForm1::Button1Click(TObject *Sender)
>    {
>        Server->SendMsg("whatever");
>    }
>
>
> Gambit
>
> 
Technical Details
Message-ID: <444e6207$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newspeer1.nwr.nac.net!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail
References: <44439c71$1@newsgroups.borland.com> <4443ca2a$1@newsgroups.borland.com> <4447a6f6$1@newsgroups.borland.com> <4447b917$3@newsgroups.borland.com> <4447c0b0$1@newsgroups.borland.com> <44480aa5$1@newsgroups.borland.com> <44491a72$1@newsgroups.borland.com> <444934c4$1@newsgroups.borland.com> <444cd08c$1@newsgroups.borland.com> <444d14c5@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,fea0b13af0f4efa8
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Eric Patterson" <eric.patterson@bepco.com>
Newsgroups: borland.public.cppbuilder.internet.socket
References: <44439c71$1@newsgroups.borland.com> <4443ca2a$1@newsgroups.borland.com> <4447a6f6$1@newsgroups.borland.com> <4447b917$3@newsgroups.borland.com> <4447c0b0$1@newsgroups.borland.com> <44480aa5$1@newsgroups.borland.com> <44491a72$1@newsgroups.borland.com> <444934c4$1@newsgroups.borland.com> <444cd08c$1@newsgroups.borland.com> <444d14c5@newsgroups.borland.com>
Subject: Re: TServerSocket SendText Exception
Date: Tue, 25 Apr 2006 13:53:12 -0400
Lines: 176
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2869
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
X-RFC2646: Format=Flowed; Original
NNTP-Posting-Host: 70.225.107.130
Message-ID: <444e6207$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1145987591 70.225.107.130 (25 Apr 2006 10:53:11 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newspeer1.nwr.nac.net!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail