"Summary" of Connect timeout processing under Linux

Source: Internet
Author: User
Tags readable set socket

1. Preface

Recently, a test tool has been written that requires fast and efficient scanning of which ports are open to each server. At that time, Ping can only detect IP, determine the server network is connected, but not to determine whether the port is open. We know that the port belongs to the application layer of the network, so need to use IP and port to detect, this time can be detected with connect, for the TCP protocol, the Connect function to carry out a TCP three handshake, if Connect is successful, then the server opened a port, If connect fails, the server is not opening a port. The Connect failure is controlled by a timeout, and in the specified time, connect initiates multiple connections and executes until time-out before returning an error. By default, connect is blocked, and the default time-out is 75s, and under normal circumstances, the connectivity of the detection network is millisecond, and if you want to judge 100,000 servers, it is inefficient to do so with the blocking default of connect. Therefore, a non-blocking connect is used and a custom timeout is required (my custom time-out is 5s).

2. Non-blocking Connect

For a blocking socket, calling the Connect function fires the three-time handshake of TCP and returns only if the connection succeeds or fails, and for non-blocking sockets, if the call to the Connect function returns 1 (indicating an error), and the error is einprogress, Indicates that the connection was established, started but not completed, and if 0 is returned, the connection is established, typically when the server and the client are on the same host.

Select is an IO multiplexing mechanism that allows a process to instruct the kernel to wait for any one of multiple events to occur, and to wake it up after one or more events occur or after a specified period of time has passed. The connect itself does not have a timeout function, and if you want to set a timeout on the IO operation of the socket, you can use the Select function.

For select and nonblocking Connect, note two: [1] When the connection is successfully established, the descriptor becomes writable, [2] When the connection is established, the descriptor becomes readable and can be written, in which case the getsockopt function can be called.

3. Implementation steps

(1) Create the socket and use FCNTL to set it to non-blocking

(2) Call the Connect function, if return 0, the connection is established, if return-1, check errno, if the value is einprogress, the connection is being established.

(3) In order to control the connection settling time, the socket descriptor is added to the read-only writable collection of select, and a timeout is set by the Select function.

(4) If the specified time is successfully established, the descriptor becomes writable; otherwise, the error message is captured with the getsockopt function

(5) Restore the file status of the socket and return it.

The test code looks like this:

1#include <stdio.h>2#include <stdlib.h>3#include <string.h>4#include <unistd.h>5#include <sys/types.h>/*See NOTES*/6#include <sys/socket.h>7#include <netinet/inch.h>8#include <fcntl.h>9#include <errno.h>Ten  One intMainintargcChar**argv) A { -     if(ARGC <3) { -printf"Please input IP and port, for example./main 120.12.34.56 80.\n"); the         return-1; -     } -  -      +     Char*IPADDR = argv[1]; -UnsignedintPort = atoi (argv[2]); +  A     intFD =0; at     structsockaddr_in addr; - fd_set FDR, FDW; -     structtimeval timeout; -     intErr =0; -     intErrlen =sizeof(err); -  inFD = socket (Af_inet,sock_stream,0); -     if(FD <0) { tofprintf (stderr,"Create socket failed,error:%s.\n", Strerror (errno)); +         return-1; -     } the  *Bzero (&AMP;ADDR,sizeof(addr)); $addr.sin_family =af_inet;Panax NotoginsengAddr.sin_port =htons (port); -Inet_pton (Af_inet, IPADDR, &addr.sin_addr); the  +     /*set socket as non-blocking*/ A     intFlags = FCNTL (FD, F_GETFL,0); the     if(Flags <0) { +fprintf (stderr,"Get Flags error:%s\n", Strerror (errno)); - Close (FD); $         return-1; $     } -Flags |=O_nonblock; -     if(Fcntl (FD, F_SETFL, flags) <0) { thefprintf (stderr,"Set Flags error:%s\n", Strerror (errno)); - Close (FD);Wuyi         return-1; the     } -  Wu     /*Linux system default time-out is 75s in case of blocking*/ -     intrc = Connect (FD, (structsockaddr*) &addr,sizeof(addr)); About     if(RC! =0) { $         if(errno = =einprogress) { -printf"Doing connection.\n"); -             /*Processing Connection*/ -Fd_zero (&FDR); AFd_zero (&FDW); +Fd_set (FD, &FDR); theFd_set (FD, &FDW); -Timeout.tv_sec =Ten; $Timeout.tv_usec =0; therc =Select(FD +1, &AMP;FDR, &AMP;FDW, NULL, &timeout); theprintf"RC is:%d\n", RC); the             /*Select call Failed*/ the             if(RC <0) { -fprintf (stderr,"Connect error:%s\n", Strerror (errno)); in Close (FD); the                 return-1; the             } About              the             /*Connection timed out*/ the             if(rc = =0) { thefprintf (stderr,"Connect timeout.\n"); + Close (FD); -                 return-1; the             }Bayi             /*[1] When the connection is successfully established, the descriptor becomes writable, rc=1*/ the             if(rc = =1&& Fd_isset (FD, &FDW)) { theprintf"Connect success\n"); - Close (FD); -                 return 0; the             } the             /*[2] When the connection is established encountered an error, the descriptor becomes readable, can also be written, rc=2 encountered this situation, can call the GetSockOpt function*/ the             if(rc = =2) { the                 if(GetSockOpt (FD, Sol_socket, So_error, &err, &errlen) = =-1) { -fprintf (stderr,"getsockopt (so_error):%s", Strerror (errno)); the Close (FD); the                     return-1; the 94                 } the  the                 if(err) { theerrno =err;98fprintf (stderr,"Connect error:%s\n", Strerror (errno)); About Close (FD); -                     return-1;101 102                 }103             }104  the         } 106fprintf (stderr,"Connect failed, error:%s.\n", Strerror (errno));107         return-1;108     } 109     return 0; the}

4. References

http://dongxicheng.org/network/non-block-connect-implemention/

Http://www.cnblogs.com/flyxiang2010/archive/2010/12/17/1909051.html

"Summary" of Connect timeout processing under Linux

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.