ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Im trying to put a timeout on a connect call, and it works fine if I try to contact www.google.com on say port 81, but for some reason if I try to connect to an unopen port on 127.0.0.1 or my router's IP, it succesds all the time.
The method I used is : first I set the socket to non-blocking, tried connecting with connect(), not bothering to check the return value because its always -1, then using select() to check if the socket could be written to.
heres my code:
Code:
bool TcpClient::Connect( const char* host,
const unsigned short port,
const unsigned short timeOut)
{
// get the IP address
struct hostent* h=gethostbyname(host);
if (!h) return false;
// create socket and set it to non-blocking
sockfd=socket(PF_INET,SOCK_STREAM,0);
fcntl(sockfd,F_SETFL,O_NONBLOCK);
// set up address structure
remoteAddr.sin_port=htons(port);
memcpy(&(remoteAddr.sin_addr.s_addr),h->h_addr,sizeof(remoteAddr.sin_addr.s_addr));
// attempt to connect
connect(sockfd,(struct sockaddr*)&remoteAddr,sizeof(struct sockaddr));
// set up file descriptor set
FD_ZERO(&fds);
FD_SET(sockfd,&fds);
// set up timeval struct
tv.tv_sec=timeOut;
tv.tv_usec=0;
// monitor the socket
if (select(sockfd+1,NULL,&fds,NULL,&tv)<=0)
{
close(sockfd);
return false;
}
return true;
}
A method I have used before is to create a signal handler function for SIGALRM, and before calling connect call alarm(timeout); and after the connect call alarm(0);
When the alarm goes off and your signal handler returns, connect will exit, and you just turn off the alarm with the alarm(0).
There are several ways for a sockets client to "connect() with timeout":
Quote:
1. Timeout with "select()"
I really wouldn't recommend this one for your situation. At best, if I was using UDP "sendto()" and "recvfrom ()", I might use "select()" to verify that the socket became writeable or readable within a specific time before I used it.
Quote:
2. Sigalarm
_john_i_'s suggestion is a good one. For example:
Code:
/* Adapted from W. Richard Stevens, "Unix Network Programming" */
oldsigfunc = signam (SIGALRM, mynewfunc);
if (alarm (nsec) != 0) {
printf ("WARNING: Alarm already set!\n");
}
/* Try to connect */
iretval = connect (sockfd, &sa, slen);
if (iretval < 0) {
close (sockfd);
if (errno == EINTR)
printf ("WARNING: timeout occurred...\n");
}
/* Clear Alarm/reset original SIGALRM handler */
alarm (0);
signal (SIGALRM, oldsigfunc);
/* ... continue or not, based on "iretval" ... */
Quote:
3. "setsockopt (SO_RCVTIMEO)"
This is the best option of all ... if your stack supports it.
My version of Stevens (the 2nd Edition, 1998) states that you CANNOT use "setsockopt(SO_RCVTIMEO)" to set a connect timeout. This is no longer true on most OS's, and it has been available on Linux since kernel 2.3.41.
<= If at all possible, I'd encourage you to consider SO_RECVTIMEO
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.