[asio-users] basic_stream_socket::async_connect -- non-blockingconnect vs async connect
Brought to you by:
chris_kohlhoff
|
From: Chauhan, V. <Vik...@an...> - 2007-09-20 16:23:17
|
Hi Chris,
Thanks for your reply. I was not sure that blocking connect and
async_connect would take the same time to connect(or fail to connect).
This would mean that I cannot reconnect in less that 21 seconds (as
typically this is the delay, when peer server is not alive).
However, I want my client socket to reconnect to server socket in less
that 5 seconds after server is alive. Do you think I can do that using
boost asio sockets?
I have used the standard select API to achieve this in my code. The
skeleton code on Windows is stated below: =20
1. Create a client socket.
2. Set it's IO in the non-blocking mode using "::ioctlsocket(handle_,
FIONBIO, &nonblocking)"=20
3. Construct the "sockaddr_in" address structure
4. Set "waitTimeOnNonBlockingSocket" =3Dthe time you want to wait before
another select call.
5. Set "selectRetryCount" =3D the number of times you wish to retry
connect with the server socket.
6. Do the following:
int connectRetValue =3D ::connect(handle_, reinterpret_cast<struct
sockaddr *>(&remoteAddress),=20
=09
sizeof(remoteAddress));
if(connectRetValue =3D=3D SOCKET_ERROR)
{
errorCode_ =3D ERRNO;
if ((errorCode_ =3D=3D WSAEWOULDBLOCK) &&
(isNonBlockingSocket))
{
{
timeval selectTimerValue;
fd_set writeFdSet;
int selectRetVal;
=09
for (unsigned int i =3D0; i<
selectRetryCount;i++)=20
{=20
selectTimerValue.tv_sec =3D
waitTimeOnNonBlockingSocket;=20
selectTimerValue.tv_usec =3D 0;=20
=09
FD_ZERO(&writeFdSet);=20
FD_SET(handle_, &writeFdSet);=20
=09
selectRetVal =3D select(NULL,
NULL, &writeFdSet, NULL, &selectTimerValue);=20
if (selectRetVal > 0) // Means
that socket connected for write=20
{
isValid_ =3D true;
break;=20
} // if(selectRetVal > 0)=20
} //for (unsigned int i =3D0; i<
selectRetryCount;i++)=20
}
}
} //if(connectRetValue =3D=3D SOCKET_ERROR)
br,
Vikas
> -----Original Message-----
> From: Christopher Kohlhoff [mailto:ch...@ko...]=20
> Sent: 19 September 2007 10:12
> To: asi...@li...
> Subject: Re: [asio-users]=20
> basic_stream_socket::async_connect-- non-blockingconnect vs=20
> async connect
>=20
> Chauhan, Vikas wrote:
> > Hello all,
> >=20
> > I think I have found the reason for this.
> >=20
> > Actually, I had the following sequence of calls earlier :
> > 1. tcp::socket::async_connect(peer_endpoint,connect_handler ).
> > 2. io_service::run()
> >=20
> > Logically, step 2 should precede step 1, but I could not do that as
> > io_service::run() was failing as there was nothing=20
> registered to it.=20
>=20
> There should be no requirement to perform the run first.=20
> Starting the async_connect gives the io_service "work" to do=20
> in any case.
>=20
> > Now, I have created an instance of =20
> "boost::asio::io_service::work "=20
> > in the beginning of program. It helps the io_service to=20
> queue any aync=20
> > calls.
> > Hence now the sequence of calls is :
> > 1. boost::asio::io_service::work(ioservice)
> > 2. io_service::run()
> > 3. tcp::socket::async_connect(peer_endpoint,connect_handler ).
> >=20
> > Thanks to those who may have tried to find out reasons for=20
> the problem.
>=20
> I'm a bit confused about what your original problem was now=20
> :) An async_connect operation should take the same length of=20
> time to complete as a blocking connect operation. E.g. if a=20
> connect takes 20 seconds then an async_connect should also=20
> take 20 seconds.
>=20
> However it now sounds like you're talking about when the=20
> completion handler itself is called, and that is only allowed=20
> to occur from within a call to io_service::run() (or run_one,=20
> poll or poll_one). You can start an async_connect and then=20
> not call io_service::run() straight away, in which case your=20
> handler won't be called until you do.
>=20
> Cheers,
> Chris
>=20
>=20
>=20
>=20
|