Network programming socket It TCP it time_wait country specific explanation

Source: Internet
Author: User
Tags ack sendmsg htons

Here we reproduce some of the problems we encountered with the simplest one-to-ones client server programming Model:

Beginners socket When writing a socket name its wonderful problem. For example, the common error returned by the BIND function is eaddrinuse


Use the following procedure to reproduce this state:

Client

int main (int argc, const char * argv[]) {struct sockaddr_in serveradd;    Bzero (&serveradd, sizeof (Serveradd));    serveradd.sin_family = af_inet;    SERVERADD.SIN_ADDR.S_ADDR = inet_addr (SERV_ADDR);        Serveradd.sin_port = htons (Serv_port);        int CONNFD = socket (af_inet, sock_stream, 0);    int connresult = connect (CONNFD, (struct sockaddr *) &serveradd, sizeof (Serveradd));        if (Connresult < 0) {printf ("Connection failed \ n");        Close (CONNFD);    return-1;    } ssize_t Writelen;    ssize_t Readlen;    Char recvmsg[65535] = {0};        Char sendmsg[20] = "I am Client";    Writelen = Write (CONNFD, sendmsg, sizeof (sendmsg));        if (Writelen < 0) {printf ("Send failed \ n");        Close (CONNFD);    return-1;    } else {printf ("Send succeeded \ n");                } while (1) {//Sleep (1);        Readlen = Read (CONNFD, recvmsg, sizeof (RECVMSG));            if (Readlen < 0) {printf ("read failed \ n"); Close (connfD);        return-1;            } if (Readlen = = 0) {printf ("Server off \ n");            Close (CONNFD);        return-1;            } printf ("Server said:%s\n", recvmsg);    } close (CONNFD); return 0;}

Server:

int main (int argc, const char * argv[]) {struct sockaddr_in serveradd;        struct sockaddr_in clientadd;    Bzero (&serveradd, sizeof (Serveradd));    serveradd.sin_family = af_inet;    SERVERADD.SIN_ADDR.S_ADDR = htonl (Inaddr_any);        Serveradd.sin_port = htons (Serv_port);        Socklen_t Clientaddrlen;        int LISTENFD = socket (af_inet, sock_stream, 0);        if (LISTENFD < 0) {printf ("Create socket failed \ n");        Close (LISTENFD);    return-1;    } int bindresult = Bind (LISTENFD, (struct sockaddr *) &serveradd, sizeof (Serveradd));        if (Bindresult < 0) {close (LISTENFD);        printf ("Bind port failed, errno =%d\n", errno);    return-1;    } else {printf ("bind Port succeeded \ n");        } Listen (LISTENFD, 20);    int CONNFD;    unsigned char recvmsg[65535];        Char replymsg[20] = "I am Server";    Clientaddrlen = sizeof (CLIENTADD);    CONNFD = Accept (LISTENFD, (struct sockaddr *) &clientadd,&clientaddrlen); if (CONNFD &LT        0) {close (LISTENFD);        printf ("Connection failed \ n");    return-1;    } else {printf ("Connection succeeded \ n");    } ssize_t Readlen = Read (CONNFD, recvmsg, sizeof (RECVMSG));    printf ("readlen:%ld\n", Readlen);        if (Readlen < 0) {printf ("read failed \ n");    return-1;        } else if (Readlen = = 0) {printf ("read complete \ n");        Close (LISTENFD);    return 0;           } printf ("Client said:%s\n", recvmsg);          while (1) {write (CONNFD, replymsg, sizeof (REPLYMSG));    } close (CONNFD); return 0;}

Execute the server program first and then the client. Then close the server and then immediately open the server, it will print such as the following information: 48 correspondingeaddrinuse Error code

failed to bind port, errno = -


Here is a question to illustrate:

When a UNIX process is terminated regardless of whether it is voluntary (calling exit or returning from the main function) or involuntary (receiving a signal to terminate the process), all open descriptive descriptors are closed, which will also cause a fin to be emitted on whatever TCP connection is still open.


It is very obvious that the server is closed. Why is the port bound to fail? The following are the four sections of the TCP connection termination :


watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvanvuanvumtuwmdeznjuy/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma== /dissolve/70/gravity/southeast ">


In some cases, the fin of the first subsection is sent along with the data. In addition, the second and third sub-sections may be merged into one sub-section.


Here our server is the one end of the active shutdown. When the fin section is actively sent to wait for confirmation, the status becomes fin_wait_1, the status becomes fin_wait_2 after receiving the confirmation, and the fin section of the client receives the state becomes time_wait state. here in The time_wait state will stay 2MSL before it enters the closed state. So we start the server immediately, the previous connection is not in the closed state, there are still people, so it will fail to bind , later will explain why there is a time_wait state;

Here the client is the end of the passive shutdown, receiving the service side of fin after the state enters close_wait, this time the Read method will return 0, and then send the confirmation of the first subsection. At this point the client calls the Close method to send the Fin section to the server to enter the last_ack state, waiting for confirmation to arrive. After receiving confirmation, the connection status becomes CLOSED;


TIME_WAIT state: The duration of the stay in this state is twice times the maximum sub-section life (maximum Segment LIFETIME,MSL). Sometimes called 2MSL. The MSL is the maximum amount of time the IP datagram can survive on the internet, up to 255. This is a hop count limit instead of a real time limit.


Time_wait Status exists for:

reliable termination of TCP full-duplex connection: may have to retransmit finally that Ack,time_wait is closed, assuming there is no time_wait 2MSL, direct closed, then assume that the last ACK was lost, is not to send an ACK again, the service will not receive the ACK is sent again finally that fin, this time the client is already closed, will respond to a RST, this RST will be interpreted by the server as a mistake.

the repeated sub-section of the agreement fades away in the network: when a TCP connection is established for each success. The old, repeated groupings from the previous incarnation of the connection have vanished in the network. This will not be misinterpreted as a grouping of new connections.


Here's another scenario: open sleep inside the clientwhile (or block out the code below the client) and then execute the server program first. After executing the client and then shutting down the server and then opening the server immediately, the binding fails, and the state is a bit different from the previous one.

if (Readlen = = 0) {            printf ("Server off \ n");            Close (CONNFD);            return-1;        }

We print from terminal information such as the following, at this time the server is in the Fin_wait_2 state, as stated above because the client has not closed the connection, did not send a third fin subsection, the client because has received from the service side of fin sub-section and is in Close_ Wait status;


wanglijuntekimac-mini:~ wanglijun$ Netstat-an |grep 8000

TCP4 0 0 192.168.1.103.8000 192.168.1.103.49632 fin_wait_2

TCP4 290960 0 192.168.1.103.49632 192.168.1.103.8000 close_wait


Workaround:

Here is a SO_REUSEADDR socket option, which can be resolved after opening, and we will include the following setup code before band:

<span style= "FONT-SIZE:12PX;" >int yes = 1;    SetSockOpt (LISTENFD,               sol_socket, so_reuseaddr,               (void *) &yes, sizeof (yes));</span>

When the server restarts the listener, attempting to bundle the port on the existing connection will fail, (another case may be that the child process that was previously derived also handles the connection) assumes that the SO_REUSEADDR socket option is set. Bind succeeds, all TCPservers should specify the so_reuseaddr socket option to consent to the server being started again in such a situation ; So_reuseaddr agreed to start multiple instances of the same server on the same port, just to bundle a different local IP address for each instance.


for TCP that we could never start bundling the same IP address and multiple servers of the same port number.


References:

"UNIX Network programmingvolume 1, third edition:thesockets Networking API"


Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.

Network programming socket It TCP it time_wait country specific explanation

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.