Im using ServerSocket and Threads (http://dn.codegear.com/article/26276).
I have problem with closing server application when some clients are
connected.
On FormClose event i have code:
ServerSocet->Active=false;
And everythink is ok when any client isn't connected.
When client is connected and im trying to close application it hang.
I think that i should disconnect client/terminate active threads befor
close application?
Best regards,
Patryk B.
You need to close the server. This then ensures the relevant TCP/IP
state packets are sent to any attached clients.
ServerSocket->Close();
Bren.
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
ServerSocket->Close();
}
It dosent work, still when some client is connected it hang out,
I need to close client, then server is closing properly.
Patryk.
> I have problem with closing server application when
> some clients are connected.
Please show the actual code that you are using. Your thread code is likely
not responding to disconnects properly.
Gambit
> You need to close the server.
He already is. All Close() does is sets the Active property to false, which
he's doing directly.
Gambit
> Please show the actual code that you are using. Your thread code is
> likely
> not responding to disconnects properly.
For test im using code from http://dn.codegear.com/article/26276
As client im using telnet. It hang beacuse i delete:
if (pStream->WaitForData(CLIENTWAITTIME))
I want disconnect client only when server is going to shutdown.
In all I can set time for few hours and for my future use it will be ok
but im
interesting how to do that.
> Gambit
>
>
Patryk.
--
Używam klienta poczty Opera Mail: http://www.opera.com/mail/
> It hang beacuse i delete:
>
> if (pStream->WaitForData(CLIENTWAITTIME))
You need that line in order to detect a graceful disconnect from the client.
When WaitForData() returns true, and then Read() returns 0, the connection
has been disconnected by the client.
> I want disconnect client only when server is going to shutdown.
Then simply remove the call to Close() when WaitForData() returns false, ie:
void __fastcall TMyServerThread::ClientExecute(void)
{
char buffer[BUFFERSIZE];
int iRead;
try
{
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,
CLIENTWAITTIME);
try
{
while( (!Terminated) && (ClientSocket->Connected) )
{
if( !pStream->WaitForData(CLIENTWAITTIME) )
continue;
iRead = pStream->Read(buffer, sizeof(buffer);
if( iRead < 1 )
{
if( iRead == 0 )
// client disconnected...
else
// socket error...
ClientSocket->Close();
}
else
{
// process buffer up to iRead bytes...
}
}
}
__finally
{
delete pStream;
}
}
catch (...)
{
// handle exception...
}
}
Gambit
Work perfectly.
Thanks for help and quick answer :)
Patryk.
"Patryk B." <pbo...@no.spam.o2.pl> escribió en el mensaje
news:op.tyk3f...@dune.intranet...
> when I close the server, the client socket believes it's active
> (Active property still set is TRUE).
As it should be. That is not what the Active property is for. You should
be looking at the Socket.Connected property instead.
> How can I detect in the client socket that the server has been shut down?
If you are using the client in non-blocking mode, then you will get an
OnDisconnect event. If you are using it in blocking mode instead, then
SendBuf() and ReceiveBuf() will return 0 the next time you write to, or read
from, the connection.
Gambit
>> when I close the server, the client socket believes it's active
>> (Active property still set is TRUE).
>
> As it should be. That is not what the Active property is for. You should
> be looking at the Socket.Connected property instead.
I tried but it's the same: ClientSocket->Socket->Connected remains TRUE
after the server socket is closed.
>
>> How can I detect in the client socket that the server has been shut down?
>
> If you are using the client in non-blocking mode, then you will get an
> OnDisconnect event. If you are using it in blocking mode instead, then
> SendBuf() and ReceiveBuf() will return 0 the next time you write to, or
> read from, the connection.
I'm working in blocking mode, but using a TWinSocketStream as in the
CodeGear example.
I guess I'll have to use these socket functions, because there's nothing I
can use in the stream.
Thanks again,
Pere
> I'm working in blocking mode
The Connected property is not accurate in blocking mode, because there is
nothing to reset it when needed. You have to use a TWinSocketStream to
read/write data, and TWinSocketStream does not make updates to
TClientSocket's properties. So you have to look at the return values of
your actual reading/writing operations instead.
When reading, if TWinSocketStream::WaitForData() returns true and then
TWinSocketStream::Read() returns 0, the connection was disconnected
gracefully. If the socket was disconnected abnormally, however, then
WaitForData() will never return true, so you have to watch out for that.
TWinSocketStream.Read() will throw an exception if it couldn't read from the
socket.
When writing, there is no waiting. If TWinSocketStream.Write() returns 0,
the socket was disconnected gracefully. If there is an error writing to the
socket, an exception is thrown.
> I guess I'll have to use these socket functions, because there's
> nothing I can use in the stream.
Yes, there is. See above.
Gambit