🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: TClientSocket handling a bad connection

#380
From: Remy Lebeau (TeamB)
Date: Mon, 31 Mar 2008 23:09
126 lines
6072 bytes
"Lesley Anne" <mspfila (dash) brl (at) yahoo (dot) com> wrote in message 
news:47f16766$1@newsgroups.borland.com...

> 2) Client calls SendText to send a message to the server.

Where exactly are you doing that?  For a non-blocking socket, where you 
execute reading/writing operations makes a difference.

> Server sees nothing.

Then the data was not transmitted at all.

> Client gets OnError event with: ErrorEvent == eeSend,
> ErrorCode == 10038 (WSAENOTSOCK)

Is the connection passing through a router or firewall?

> Within the OnError event handler, Client calls Socket->Close()
> No OnDisconnect events occur

It has to be.  TCustomWinSocket.Close() fires the OnDisconnect event handler 
directly before then destroying the socket handle.

> and Client remains Active.

The only way it can be active after Close() is called is if the seDisconnect 
notification is never being processed at all.

> 3) Every second, the Client calls SendText a few more times.
> Nothing reaches the server.

Then the client is not actually connected to the server.

> 4) After 5 minutes, the server times out, deciding that this connection 
> (which it hasn't received anything on) is bad, so closes it.
> Server gets OnDisconnect event.
> Client sees nothing.

Then the client is not actually connected to the server.

> 5) Client (which is still Active and has never gotten an OnDisconnect
> event) continues trying to send on this connection which had never
> worked properly and which now no longer even exists at the server's end.

This suggests there are bugs in your code that are preventing TClientSocket 
from operating properly in the first place.

> I think part of the fix is likely to be that I should redesign the client 
> app to be multi-threaded so that I can use blocking sockets.

That is not necessary.  TClientSocket in non-blocking mode works just fine 
when used properly.  It has been a very solid and stable component for a 
long time.

> That way at least the client will be able to recognize that the SendText
> didn't work

You need to use a TWinSocketStream when reading/writing a blocking socket. 
You can't use SendText() or SendBuf() anymore.

> in time for me to avoid removing the message from the FIFO queue
> I use for spooling messages that need to be sent.

That in itself tells me that you are probably not managing the queue 
properly.  For one thing, you must look at the return value of SendText() or 
SendBuf() in order to know if the entire string was sent at all.  If it is 
not, and the result is -1 without an OnError event being triggered, then you 
must wait for the OnWrite event to fire and then re-sent the same data again 
before then sending any subsequent new data.

> Both sides of the connection did see the OnConnect event.
> Shouldn't that indicate that the connection was established
> successfully?

Perhaps, but that does not account for any mismanagement you may be doing 
after connecting.  It also does not take into account if a firewall/router 
is forcibly killing the socket endpoint on the client side after connecting.

> So why does the client get the WSAENOTSOCK error when it tries to send?

You are likely trying to send the data too early.  Between when Open() is 
called and the OnConnect event is fired, you cannot sent data to the socket. 
It is not ready yet.  You must wait for the OnConnect event first.  You also 
must wait for the OnWrite event if SendText() or SendBuf() ever return -1 
without firing the OnError event.

> And why does it never get the OnDisconnect event?

Are you assigning a handler to the client's OnSocketEvent event, by chance?

> If the connection is down, how can I force the client to recognize
> that it's down so that I can stop sending and try to reconnect until
> I get a working connection?

Find and fix the bug in your your client code that is preventing the 
TClientSocket from operating correctly.

> Calling Socket->Close from the OnError event was an attempt to do this.
> I was hoping that would bring down the client side of the non-functioning
> "connection", so I could re-establish it.

Under normal situations, it does.

> void __fastcall TCnamForm::PerSecondTimer(TObject *Sender)

>         BEClientSocket->Socket->SendText(Message + "\n");

You are completely ignoring the return value of SendText().  You must check 
it to know how much data was actually sent, adjusting the FIFO item to 
account for partial transmissions and blocking transmissions.

> One of my problems here is that, since I'm in non-blocking mode,
> that try-catch around SendText isn't really doing anything very useful.

An exception would only be raised if the OnError event handler does not set 
the ErrorCode value to 0.

> That's why I think I need to redesign this to use blocking sockets, so
> I can see whether the send really was successful before deciding
> whether I can take the message off of the spool.

You can do that with a non-blocking socket as well.


Gambit 
Technical Details
Message-ID: <47f16f19$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!proxad.net!feeder1-2.proxad.net!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <47f16766$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,74b475fd14f26423
X-Google-Attributes: gid11508e,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.internet.socket
References: <47f16766$1@newsgroups.borland.com>
Subject: Re: TClientSocket handling a bad connection
Date: Mon, 31 Mar 2008 16:09:02 -0700
Lines: 128
Organization: Lebeau Software
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-RFC2646: Format=Flowed; Response
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198
NNTP-Posting-Host: 207.178.157.90
Message-ID: <47f16f19$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1207004953 207.178.157.90 (31 Mar 2008 16:09:13 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!proxad.net!feeder1-2.proxad.net!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail