Thread: Check if a host is alive

  1. #1
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230

    Check if a host is alive

    Hi, I'm trying to write a function to check if a host is alive in a given specific time frame. For example, say I wanted to give this function 5 seconds to check if the host is alive, if a connection cannot be established properly within 5 seconds then I presume the host is down and return 1, otherwise I return 0.

    For some reason this function ALWAYS returns 0 even if the host is not alive (aka it thinks the host is alive for some reason...) and the variable 'ret' is always equal to 1.

    I'm trying to use a non-blocking socket, then a call to connect and then a call to select with that specific time limit to check if the host is up. I cannot seem to get it working.

    Code:
    // checks whether host is alive with a non-blocking socket and call to select on minimal timeout
    int Host_Alive(arguments * args) {
    	args->serv.sin_addr.S_un.S_addr = inet_addr(args->sz_address);
    	args->serv.sin_family = AF_INET;
    	args->serv.sin_port = htons(args->port);
    
    	args->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    	args->sz_address = new char[16];
    	strcpy(args->sz_address, inet_ntoa((in_addr)args->serv.sin_addr));
    
    	unsigned long iMode = 0;
    	ioctlsocket(args->sockfd, FIONBIO, &iMode); // put socket in non-blocking state
    
    	connect(args->sockfd, (const sockaddr *)&args->serv, sizeof(args->serv));
    	
    	fd_set socket_set;
    	timeval timer;
    
    	socket_set.fd_array[0] = args->sockfd;
    	socket_set.fd_count = 1;
    
    	timer.tv_sec = args->timeout;
    	
    	int ret = select(0, &socket_set, &socket_set, &socket_set, &timer);
    	
    	if (!ret || ret == SOCKET_ERROR) {
    		printf(" [!] Host %s:%d not alive: %d!\n", args->sz_address, args->port, ret);
    		free(args);
    		closesocket(args->sockfd);
    		return 0;
    	}
    
    	else
    		printf(" [!] Host up: %d!\n", ret);
    	
    	free(args);
    	closesocket(args->sockfd);
    
    	return 1;
    }
    Thanks!
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    re-read your manpage: with connect() in non-blocking mode, you must call it again after the timeout (in your case) to check if the connection is still in progress or completed (see EALREADY).

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Right now select() will check the read fd set first. It sees your socket cannot be read from, so it will zero out the index for that socket. Once it does that it will never even check to see if the socket is writable which is what you want in the first place.

    Change your select() call to:
    Code:
    int ret = select(0, NULL, &socket_set, NULL, &timer);

  4. #4
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    I did what you said bithub, but now instead of it always saying the host is alive, the call to select() blocks infinitely. Also, I changed iMode to 1, because I'm pretty sure 1 is for non-blocking and 0 is for blocking (which I missed when I was reading it the first time).

    So what else is wrong here? :/ I've been trying to fix this for days! Thanks.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    the problem is that while the socket is not connected, I don't see what select() could do, you're assuming the connection procedure is a regular i/o operation, on which ground do you make this assumption? the manpage tells connect() with a non-blocking fd is a particular case; I don't think select() can be used here. You're making things really complicated, create a non-blocking socket, call connect() once, set a timer, on timeout call connect() again to see if it succeeded or not and you're done...

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by root4 View Post
    the problem is that while the socket is not connected, I don't see what select() could do, you're assuming the connection procedure is a regular i/o operation, on which ground do you make this assumption? the manpage tells connect() with a non-blocking fd is a particular case; I don't think select() can be used here. You're making things really complicated, create a non-blocking socket, call connect() once, set a timer, on timeout call connect() again to see if it succeeded or not and you're done...
    select() can be used on a non-connected socket. That's how we do non-blocking connect() calls; it's very common.

    pobri19:
    You should not directly access the members of the fd_set structure. Use the defined macros FD_ZERO and FD_SET to manipulate the fd_set structure.

  7. #7
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Quote Originally Posted by root4 View Post
    You're making things really complicated, create a non-blocking socket, call connect() once, set a timer, on timeout call connect() again to see if it succeeded or not and you're done...
    Hey, thanks a lot for suggesting this. This is exactly what I was after but didn't think of it until you mentioned it Cheers.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by pobri19 View Post
    Hey, thanks a lot for suggesting this. This is exactly what I was after but didn't think of it until you mentioned it Cheers.
    That's not a good way to handle a non-blocking connect. How long do you set the timer for? 10 seconds? So if it takes 1 second, does your application wait another 9 seconds before it realizes the connect succeeded? You don't want that, so maybe make your timer go off every second and check if the connect succeeded. Now you are basically polling the socket. If that's the case, why have a timer at all? You could just make a while loop that sleeps for a second, then checks the socket.

    Or you could just use the method that all the other programmers use which is the select() call.

    I modified your code a little bit, and guess what... it works just fine.
    Code:
    int Host_Alive() {
    	WSAData data;
    	WSAStartup( MAKEWORD(2,2), &data);
    	sockaddr_in serv;
    	SOCKET sockfd;
    	serv.sin_addr.S_un.S_addr = inet_addr("209.85.171.100"); // google's IP
    	serv.sin_family = AF_INET;
    	serv.sin_port = htons(80);
    
    	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     
    	unsigned long iMode = 0;
    	ioctlsocket(sockfd, FIONBIO, &iMode); // put socket in non-blocking state
    
    	int ret = connect(sockfd, (struct sockaddr*)&serv, sizeof(serv)); 
    	if(ret == -1 && WSAGetLastError() != WSAEWOULDBLOCK)
    	{
    		printf("Error, connect() failed [%d]\n", WSAGetLastError());
    		closesocket(sockfd);
    		return 0;
    	}
     
    	fd_set socket_set;
    	timeval timer;
     
    	FD_ZERO(&socket_set);
    	FD_SET(sockfd, &socket_set);
     
    	timer.tv_sec = 5;
    	timer.tv_usec = 0;
     
    	printf("About to select\n");
    	ret = select(0, NULL, &socket_set, NULL, &timer);
    	printf("Select returned %d\n", ret);
    	if (!ret || ret == SOCKET_ERROR) {
    		printf("host not alive\n");
    		closesocket(sockfd);
    		return 0;
    	}
     
    	else
    		printf("[!] Host up!\n");
     
    	closesocket(sockfd);
     
    	return 1;
    }

  9. #9
    Registered User
    Join Date
    May 2008
    Location
    Australia
    Posts
    230
    Quote Originally Posted by bithub View Post
    That's not a good way to handle a non-blocking connect. How long do you set the timer for? 10 seconds? So if it takes 1 second, does your application wait another 9 seconds before it realizes the connect succeeded? You don't want that, so maybe make your timer go off every second and check if the connect succeeded. Now you are basically polling the socket. If that's the case, why have a timer at all? You could just make a while loop that sleeps for a second, then checks the socket.

    Or you could just use the method that all the other programmers use which is the select() call.
    Hey thanks for the reply, you raise a very valid point, I didn't even consider it until you mentioned it I used the example you showed me, turns out you need to initialize the structures usec member to 0 or select() fails. I'll get back to you if I have any more problems or if the solution worked thanks!

    Edit: Yep, worked well Cheers again!
    Last edited by pobri19; 05-05-2009 at 01:57 AM.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    select() can be used on a non-connected socket. That's how we do non-blocking connect() call
    fine, thanks for that, I never had the chance to work on this timed connect() problem but as this is the 2nd thread on the topic (left unresolved in the old one), I assumed select() simply did not work in this case (and didn't even try to work on the code, shame on me), but this is indeed a better solution than a fixed timeout, I do agree.

    Or you could just use the method that all the other programmers use
    good joke ;-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BN_CLICKED, change button style
    By bennyandthejets in forum Windows Programming
    Replies: 13
    Last Post: 07-05-2010, 11:42 PM
  2. How can i check a directory for certain files?
    By patrioticpar883 in forum C++ Programming
    Replies: 13
    Last Post: 02-01-2008, 05:27 PM
  3. how to check input is decimal or not?
    By kalamram in forum C Programming
    Replies: 3
    Last Post: 08-31-2007, 07:07 PM
  4. Please check this loop
    By Daesom in forum C++ Programming
    Replies: 13
    Last Post: 11-02-2006, 01:52 AM
  5. check my code ( if statement, file existance )
    By Shadow in forum C Programming
    Replies: 1
    Last Post: 10-04-2001, 11:13 AM