Article View: borland.public.cppbuilder.internet.socket
Article #2410Re: TServerSocket SendText Exception
From: Eric Patterson
Date: Tue, 25 Apr 2006 17:53
Date: Tue, 25 Apr 2006 17:53
174 lines
7169 bytes
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-mailReferences:
<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