In recent projects, there is a need to detect whether an IP address is a pass-through, using the socket's connect function. However, when the IP address is incorrectly written, connect will always be blocked there for about 2 or 3 minutes to return to the connection failure. This is unacceptable to the user. The following article describes two ways to implement this time-out setting:
Transfer from http://blog.csdn.net/ast_224/article/details/2957294
Connect Timeout:
The current way to set the socket connect timeout for each platform is through select (), as follows:
1 . establish sockets; 2 . Set the socket to non-blocking mode; 3 . Call connect (); 4 . Use Select () to check if the socket descriptor is writable; 5 the Connect () results are judged based on the results returned by select (). 6. Set the socket back to blocking mode.
//set socket to non-blockingUnsignedLongUl=1; intRm=ioctl (sockfd,fionbio,&ul); if(rm==-1) {close (SOCKFD); return 0; } if(Connect (SOCKFD,structSOCKADDR *) &their_addr,sizeof(structSOCKADDR)) = =0) {printf ("connected/n");//Normal connection (small: When debugging with GDB, never go to this step "set to non-blocking, connect call, regardless of whether the connection is established immediately return-1") } if(errno!=einprogress)//If errno is not einprogress, then an error occurs (einprogress: When the connection is made in a non-blocking manner, the returned result if it is-1, does not mean that the connection has been faulted, if its return result is einprogress, That means the connection is still in progress.){perror ("Connect"); printf ("cannot connect:%s/n", server); return 0; } //setting timeouts with select structtimeval timeout; Fd_set R; Fd_zero (&R); Fd_set (SOCKFD,&R); Timeout.tv_sec=0; Timeout.tv_usec= -; intretval =Select(sockfd+1,null,&r,null,&timeout); if(retval==-1) {perror ("Select"); return 0; } Else if(RetVal = =0) {fprintf (stderr,"timeout/n"); return 0; } printf ("%sconnected/n", server); //set the socket back to normal blocking modeul1=0; RM=ioctl (Sockfd,fionbio, (unsignedLong*) &ul1); if(rm==-1) {close (SOCKFD); return 0; }
The above code works well, and the exact information about the connection error can also be obtained through getsockopt (), but the total method is inevitably somewhat complicated, as it involves the release and return of the blocking state.
Here is a simple method of operation, you can also set the connection time-out: that is, by so_sndtimo the set of node character parameters.
The reason is: the Linux kernel source code in connect the timeout parameter and the So_sndtimo operation parameters are consistent.
Therefore, under the Linux platform, you can set the So_sndtimo to control the connection timeout before connecting via connect.
structTimeval Timeo; socklen_t Len=sizeof(Timeo); Timeo.tv_sec=overtime; if(SetSockOpt (SOCKFD, Sol_socket, So_sndtimeo, &timeo, len) = =-1) {strcpy (Reason,strerror (errno)); Perror ("setsockopt"); return 0; } their_addr.sin_family=af_inet; Their_addr.sin_port= Htons (serverstruct->port); Their_addr.sin_addr= *((structIN_ADDR *) he->h_addr); Bzero (& (Their_addr.sin_zero),8); if(Connect (SOCKFD,structSOCKADDR *) &their_addr,sizeof(structSOCKADDR)) = =-1) { if(errno = =einprogress) {strcpy (reason,"Timeout"); return 0; } strcpy (Reason,strerror (errno)); Perror ("Connect"); return 0; }
Small: Both of these implementations can achieve the goal. The second is relatively simple, using the parameters directly modified by the Connect internal implementation. But this approach may have other problems, right? (I'm not sure), may affect the timeout setting for other socket programming interfaces. According to So_sndtimo literal meaning, is the meaning of send time out, the feeling may affect some of the functions of sending data, such as send
Timeout setting for Connect socket