From: cerr on
Hi There,

I have an application that tries to establish a TCP connection to a
server usingf connect. If the server does not exist it seems as if it
tries foirever before it eventually times out. How can i reduce this
timeout?
I'm interested in knowing fast er that the connection can not be
established.

Thanks,
Ron

My connect method:

int PIDClient::OpenPIDTCPSocket(int iPort, string iHost, sockaddr_in
*iSockAddr)
{
int iSock = -1;
int n;
char Buf[100];
struct timeval tv;

iSock = socket(AF_INET,SOCK_STREAM,0);
if( iSock == -1){
return -1;
}

tv.tv_sec = 1;
tv.tv_usec = 0;

bzero(iSockAddr,sizeof(iSockAddr));
(*iSockAddr).sin_family = AF_INET; // host byte order
(*iSockAddr).sin_port = htons(iPort); // short, network byte order
(*iSockAddr).sin_addr.s_addr = inet_addr(iHost.c_str());

setsockopt(iSock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(tv));
setsockopt(iSock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv));

n = connect(iSock,(struct sockaddr *)iSockAddr,sizeof(struct
sockaddr));

if(n < 0){
gettimeofday(&logTime, NULL);
sprintf(Buf,"PID thread error conneting socket errno=%i", errno);
// send log message out only every 30 seconds
//(need both values in the condition cause tv_sec is from 0 to 59)
if (logTime.tv_sec==0 || logTime.tv_sec==30){
log->write(Buf, logger::DEBUG);
}
}

return iSock;
}
From: cerr on
On Mar 10, 1:41 pm, cerr <ron.egg...(a)gmail.com> wrote:
> Hi There,
>
> I have an application that tries to establish a TCP connection to a
> server usingf connect. If the server does not exist it seems as if it
> tries foirever before it eventually times out. How can i reduce this
> timeout?
> I'm interested in knowing fast er that the connection can not be
> established.
>
> Thanks,
> Ron
>
> My connect method:
>
> int PIDClient::OpenPIDTCPSocket(int iPort, string iHost, sockaddr_in
> *iSockAddr)
> {
>         int iSock = -1;
>         int n;
>         char Buf[100];
>         struct timeval tv;
>
>         iSock = socket(AF_INET,SOCK_STREAM,0);
>         if( iSock == -1){
>           return -1;
>         }
>
>         tv.tv_sec = 1;
>         tv.tv_usec = 0;
>
>         bzero(iSockAddr,sizeof(iSockAddr));
>         (*iSockAddr).sin_family = AF_INET;     // host byte order
>         (*iSockAddr).sin_port = htons(iPort); // short, network byte order
>         (*iSockAddr).sin_addr.s_addr = inet_addr(iHost.c_str());
>
>         setsockopt(iSock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(tv));
>         setsockopt(iSock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv));
>
>         n = connect(iSock,(struct sockaddr *)iSockAddr,sizeof(struct
> sockaddr));
>
>         if(n < 0){
>           gettimeofday(&logTime, NULL);
>           sprintf(Buf,"PID thread error conneting socket errno=%i", errno);
>           // send log message out only every 30 seconds
>           //(need both values in the condition cause tv_sec is from 0 to 59)
>           if (logTime.tv_sec==0 || logTime.tv_sec==30){
>             log->write(Buf, logger::DEBUG);
>           }
>         }
>
>         return iSock;
>
>
>
> }

I believe I've figured it out:
Can I just make a fcntl(iSock, F_SETFL, O_NONBLOCK); before connect?
That seems to take care of it... but i'm not exactly sure what
downside this has.... any hints?
From: Rick Jones on
cerr <ron.eggler(a)gmail.com> wrote:
> I believe I've figured it out:
> Can I just make a fcntl(iSock, F_SETFL, O_NONBLOCK); before connect?
> That seems to take care of it... but i'm not exactly sure what
> downside this has.... any hints?

Well, the socket is non-blocking now - so if you were counting say on
a send() call with 65536 bytes to not complete before it finished
getting the 65536th byte into the stack you will have issues - ie a
send() call can complete before all the bytes go into the stack.

IIRC a connec() return on a non-blocking socket doesn't mean the
connect() has actually completed - you cannot just turn around and
start writing to the socket (IIRC) but need to wait in a select() or
poll() - with a timeout of your own chosing - until the socket
becomes, well, writable I guess, which will indicate the connection is
actually established.

rick jones
--
firebug n, the idiot who tosses a lit cigarette out his car window
these opinions are mine, all mine; HP might not want them anyway... :)
feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...
From: Nicolas George on
Rick Jones wrote in message <hn955b$5rq$1(a)usenet01.boi.hp.com>:
> Well, the socket is non-blocking now - so if you were counting say on

He can put it back to blocking when the socket is connected.

> a send() call with 65536 bytes to not complete before it finished
> getting the 65536th byte into the stack you will have issues - ie a
> send() call can complete before all the bytes go into the stack.

That is not necessarily true with a blocking socket either. If the socket
can take 32k without blocking, then a non-blocking socket will accept 32k
(the return value of send will be 32k), and then fail with EAGAIN. A
blocking can possibly block until all 64k are accepted, or just accept 32k
on the first call, and then block until it can accept some more.

All low-level read and writes must be wrapped in loops to ensure that all
the data is read or written.

> IIRC a connec() return on a non-blocking socket doesn't mean the
> connect() has actually completed - you cannot just turn around and
> start writing to the socket (IIRC) but need to wait in a select() or
> poll() - with a timeout of your own chosing - until the socket
> becomes, well, writable I guess,

Yes, writable.

> which will indicate the connection is
> actually established.

Or failed. The status can be retrieved using setsockopt(SO_ERROR).
From: cerr on
On Mar 10, 2:06 pm, Rick Jones <rick.jon...(a)hp.com> wrote:
> cerr <ron.egg...(a)gmail.com> wrote:
> > I believe I've figured it out:
> > Can I just make a fcntl(iSock, F_SETFL, O_NONBLOCK); before connect?
> > That seems to take care of it... but i'm not exactly sure what
> > downside this has.... any hints?
>
> Well, the socket is non-blocking now - so if you were counting say on
> a send() call with 65536 bytes to not complete before it finished
> getting the 65536th byte into the stack you will have issues - ie a
> send() call can complete before all the bytes go into the stack.
>
> IIRC a connec() return on a non-blocking socket doesn't mean the
> connect() has actually completed - you cannot just turn around and
> start writing to the socket (IIRC) but need to wait in a select() or
> poll() - with a timeout of your own chosing - until the socket
> becomes, well, writable I guess, which will indicate the connection is
> actually established.
>
> rick jones
> --
> firebug n, the idiot who tosses a lit cigarette out his car window
> these opinions are mine, all mine; HP might not want them anyway... :)
> feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...

Hmm, i'm having troubles understanding select exactly...
Would something like this do it:?
fd_set wset;
tv.tv_sec=1;
FD_ZERO(&wset);
FD_SET(PIDlist[pid].Socket, &wset);
int ret = select(PIDlist[pid].Socket + 1, NULL, &wset, NULL, &tv);
if (!ret)
Timeout();
else
send(...);

it compiles but i unfortunately don't have a server around to connect
to but wanna make sure what i'm doing is correct..

Thanks,
Ron