🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: TServerSocket SendText Exception

#2403
From: Remy Lebeau (TeamB)
Date: Mon, 24 Apr 2006 18:08
153 lines
6485 bytes
"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: <444d14c5@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newshub.sdsu.edu!logbridge.uoregon.edu!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>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,fea0b13af0f4efa8
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.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>
Subject: Re: TServerSocket SendText Exception
Date: Mon, 24 Apr 2006 11:08:43 -0700
Lines: 155
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 68.69.17.41
Message-ID: <444d14c5@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1145902277 68.69.17.41 (24 Apr 2006 11:11:17 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newshub.sdsu.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail