Socket Programming Practice (9)--Socket IO Timeout setting method

Source: Internet
Author: User
Tags socket error

Citation: Timeout setting 3 scenarios

1. Alarm Timeout Setting method

Code implementation: This method is less used with void sighandlerforsigalrm (int signo) {    return;} Signal (SIGALRM, SIGHANDLERFORSIGALRM); alarm (5); int ret = read (SOCKFD, buf, sizeof (BUF)); if (ret = = 1 && errno = = EINTR) {    //timeout interrupted by clock    errno = etimedout;} else if (ret >= 0) {    //Normal return (no timeout), the alarm is turned off    alarm (0);}

2. Socket options: So_sndtimeo, So_rcvtimeo

Call setsockopt to set the read/write timeout time

Example: Read timeout int seconds = 5;if (setsockopt (SOCKFD, Sol_socket, So_rcvtimeo, &seconds, sizeof (seconds)) = =-1)    err _exit ("setsockopt error"); int ret = read (SOCKFD, buf, sizeof (BUF)); if (ret = =-1 && errno = = Ewouldblock) {    // Timed out, interrupted by clock    errno = etimedout;}

3. Select mode [emphasis]

_timeout function Encapsulation

1. Read_timeout Package

/** *read_timeout-read timeout detection function, does not contain read operation * @fd: File descriptor * @waitSec: Wait timeout seconds, 0 means no detection timeout * SUCCEEDED (not timed out) returned 0, failed returns-1, timeout returned-1 and errno = Etimedo    Ut**/int read_timeout (int fd, long waitsec) {int returnvalue = 0;        if (Waitsec > 0) {fd_set readset;        Fd_zero (&readset);    Fd_set (Fd,&readset);        add struct timeval waitTime;        Waittime.tv_sec = waitsec;       waittime.tv_usec = 0; Set the microsecond to 0 (not set), and if set, the time will be more accurate do {returnvalue = select (Fd+1,&readset,null,null,&waittim        e);   } while (ReturnValue < 0 && errno = = eintr);   Wait for the interrupt (signal) to restart the Select if (returnvalue = = 0)//In the waittime time period an event also did not reach {returnvalue =-1;        Return-1 errno = etimedout;    } else if (returnvalue = = 1)//in waittime time period there is an event generated returnvalue = 0; Returns 0, which indicates success//if (returnvalue = =-1) and (errno! = eintr), then directly returns-1 (returnvalue)} return returnvalue;}



3. accept_timeout function Encapsulation

/** *accept_timeout-with timeout of accept * @fd: File descriptor * @addr: Output parameter, return address * @waitSec: Wait timeout seconds, 0 means no time-out detection, accept with normal mode successful (not timed out) return 0 , the failure returns-1, the timeout returns-1 and errno = etimedout**/int accept_timeout (int fd, struct sockaddr_in *addr, long waitsec) {int RETURNV    alue = 0;        if (Waitsec > 0) {fd_set acceptset;        Fd_zero (&acceptset);    Fd_set (Fd,&acceptset);        add struct timeval waitTime;        Waittime.tv_sec = waitsec;        waittime.tv_usec = 0;        do {returnvalue = select (Fd+1,&acceptset,null,null,&waittime);        } while (ReturnValue < 0 && errno = = eintr);            if (returnvalue = = 0)//no event generated in waittime time period {errno = Etimedout;        return-1;    } else if (returnvalue = =-1)//error return-1; /**select correctly returns: Indicates that there is an event waiting for a select: The peer has completed three handshake, the client has a new link established, and then call accept will not block the */socklen_t Socklen =    sizeof (struct sockaddr_in); if (addr! = NULL) returnvalue = Accept (FD, (struct sockaddr *) addr,&socklen);    else ReturnValue = accept (fd,null,null); return returnvalue;}

4. connect_timeout function Encapsulation

(1) Why do we need this function?

TCP/IP when the client connects to the server, if an exception occurs, the time that connect (if it is blocked by default) is RTT (which is equivalent to the client blocking for such a long time, the customer needs to wait for such a long time, obviously this client user experience is not good ( 1.5RTT time required to complete three handshake); it can cause serious software quality degradation.

(2) How to achieve connect_timeout?

1) The SOCKFD first becomes non-blocking; Then try to connect, if the network is in good condition, then immediately establish a link and return, if the network condition is not good, then the link will not be established immediately, then need our participation: Call Select, set the wait time, through the Select Manager to monitor SOCKFD, once can establish a link, Then go back and build a link that will greatly improve the quality of our software.

2) Note: The Select mechanism monitors to SOCKFD writable (that is, when a link can be established), and does not mean that the call to connect will succeed (resulting in SOCKFD can be written in two cases: a. Real links can be built up; B. An error occurred during link creation, and then the error will write back the error message, resulting in sockfd writable);

do a fault tolerance by calling getsockopt (see the following example)!

(3) Code implementation:

/** Set File descriptor FD is non-blocking/blocking mode **/bool setunblock (int fd, bool unBlock) {int flags = FCNTL (FD,F_GETFL);    if (flags = =-1) return false;    if (unBlock) flags |= O_nonblock;    else flags &= ~o_nonblock;    if (fcntl (fd,f_setfl,flags) = =-1) return false; return true;} /** *connect_timeout-connect * @fd: File descriptor * @addr: The opposite address to be connected * @waitSec: Wait timeout seconds, 0 for accept with normal mode (not timed out) return 0, Failure returns-1, timeout returned- 1 and errno = etimedout**/int connect_timeout (int fd, struct sockaddr_in *addr, long waitsec) {if (waitsec > 0)//    Set to non-blocking mode Setunblock (FD, True);    socklen_t addrlen = sizeof (struct sockaddr_in);    First try to link int returnvalue = connect (fd, (struct sockaddr *) addr,addrlen);        If the first attempt fails (and errno = = Einprogress indicates that the connection is being processed), then we need to intervene if (ReturnValue < 0 && errno = = einprogress) {        Fd_set Connectset;        Fd_zero (&connectset);        Fd_set (Fd,&connectset);        struct Timeval waitTime;        Waittime.tv_sec = waitsec;waittime.tv_usec = 0; Do {/* Once the link is established, the socket is writable */returnvalue = select (Fd+1, NULL, &connectset, NULL, &waittime)        ;        } while (ReturnValue < 0 && errno = = eintr);        if (returnvalue = =-1)//error return-1;            else if (returnvalue = = 0)//timeout {returnvalue =-1;        errno = Etimedout;            } else if (returnvalue = = 1)//return correctly, there is a socket writable {/** because Connectset has only one file descriptor, Fd_isset's test is saved **/ /** Note: There are two cases where sockets can be written: 1. Connection established successfully 2. Socket generation error (but at this point the select is correct, so the error message is not saved in errno), you need to call Getsock            OPT get */int err;            socklen_t Errlen = sizeof (ERR);            int sockoptret = getsockopt (Fd,sol_socket,so_error,&err,&errlen);            if (Sockoptret = =-1) return-1;            Test the value of err if (err = = 0)//is indeed a link established successfully returnvalue = 0;         else//connection generated an error   {errno = err;            returnvalue =-1;    }}} if (Waitsec > 0) setunblock (fd, FALSE); return returnvalue;}

/** test: Use Connect_timeout's client-side complete code (server side as before) **/int main () {int SOCKFD = socket (af_inet, sock_stream, 0);    if (SOCKFD = =-1) err_exit ("Socket error");    struct sockaddr_in serveraddr;    serveraddr.sin_family = af_inet;    Serveraddr.sin_port = htons (8001);    SERVERADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");    int ret = Connect_timeout (SOCKFD, &AMP;SERVERADDR, 5);        if (ret = =-1 && errno = = etimedout) {cerr << "timeout ..." << Endl;    Err_exit ("Connect_timeout error");    } else if (ret = =-1) err_exit ("Connect_timeout error");    Acquiring and printing peer-to-peer information struct sockaddr_in peeraddr;    socklen_t Peerlen = sizeof (PEERADDR);    if (Getpeername (SOCKFD, (struct sockaddr *) &peeraddr, &peerlen) = =-1) err_exit ("Getpeername"); cout << "Server information:" << Inet_ntoa (peeraddr.sin_addr) << "," << ntohs (PE    Eraddr.sin_port) << Endl; Close (SOCKFD);}

Attached-rtt (round-trip time) introduces:

RTT round trip delay: In the computer network it is an important performance indicator, indicating that the data sent from the sender to start, to the sender received from the receiving end of the acknowledgement (the receiving side received the data immediately sent confirmation), the total experience of the delay.

The RTT is determined by three parts: that is, the propagation time of the link, the processing time of the end system, and the queuing and processing time in the router's cache. Where the value of the previous two parts is relatively fixed as a TCP connection, the queuing and processing time in the router's cache varies with the overall network congestion level. Therefore, the change of RTT reflects the change of network congestion degree to some extent. In simple terms, the sender starts from sending data to the time it takes to receive confirmation from the receiving party.

Socket Programming Practice (9)--Socket IO Timeout setting method

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.