From: cerr on 10 Mar 2010 16:41 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 10 Mar 2010 16:54 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 10 Mar 2010 17:06 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 10 Mar 2010 17:27 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 10 Mar 2010 17:29
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 |