Socket programming Small problem: Address has been used--address already in use__ programming

Source: Internet
Author: User
Tags set socket htons

Many socket programming beginners may encounter the problem: if the first CTRL + C to end the server program, restart the server will appear address already in the use of this error, or your program in the normal shutdown server socket still have this problem. Just like this simple socket program below.

Server.c

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define BUFFER_SIZE int main () {char b Uf[buffer_size]; int SERVER_SOCKFD, CLIENT_SOCKFD; int sin_size=sizeof (struct sockaddr_in); struct sockaddr_in server_address; struct sockaddr_in client_address; memset (&server_address,0,sizeof (server_address)); server_address.sin_family = af_inet; SERVER_ADDRESS.SIN_ADDR.S_ADDR = Inaddr_any; Server_address.sin_port = htons (12000); Create a server-side socket if ((SERVER_SOCKFD = socket (af_inet, sock_stream, 0) <0) {perror ("SERVER_SOCKFD creation Failed"); Exi T (exit_failure); Bind the socket to the server's network address if (Bind (SERVER_SOCKFD, (struct sockaddr *) &server_address,sizeof (struct sockaddr)) <0) { Perror ("Server socket bind failed"); Exit (Exit_failure); //Establish a listening queue listen (server_sockfd,5); Wait for the client connection request to reach client_sockfd=accept (SERVER_SOCKFD, struct sockaddr *) &cLient_address, (socklen_t*) &sin_size); if (client_sockfd<0) {perror ("Accept client socket failed"); exit (exit_failure);}//Receive client data if (recv, buf,buffer_size,0) <0) {perror ("Recv client data Failed"); exit (exit_failure);} printf (Receive from client:%s/n BUF); Send data to Client if (send (CLIENT_SOCKFD, "I have received your message.", buffer_size,0) <0) {perror ("Send failed"); exit ( Exit_failure); Close (CLIENT_SOCKFD); Close (SERVER_SOCKFD); Exit (exit_success); }

Client.c

#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define BUFFER_SIZE int main () {char b Uf[buffer_size]; int CLIENT_SOCKFD; int Len; struct sockaddr_in address;//server-side network address structure body int result; CLIENT_SOCKFD = socket (af_inet, sock_stream, 0);//Establish client socket address.sin_family = af_inet; ADDRESS.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); Address.sin_port = htons (12000); Len = sizeof (address); Establish a connection with a remote server result = Connect (CLIENT_SOCKFD, (struct sockaddr *) &address, Len); if (result<0) {perror ("Connect failed"); exit (exit_failure);} printf ("Please input the message:"); scanf ("%s", buf); Send (client_sockfd,buf,buffer_size,0); Recv (client_sockfd,buf,buffer_size,0); printf ("Receive data from server:%s/n", buf); Close (CLIENT_SOCKFD); return 0; }

After a successful run for the first time, when you start the server-side program again, the./server becomes evil, and in the bind () This function actually appears the address already in use this error.

Then you start to get confused, do you forget to turn the socket off, or close the socket in the wrong order. After all the speculation and experimentation, you find that the problem has not progressed ... After a while, when you try again with the attitude again in the Linux "Black Terminal" input./server, the program actually ran, what situation. The reason is that the socket option in the mischief. The following is a detailed explanation of this situation on the IBM official web site, see http://www.ibm.com/developerworks/cn/linux/l-sockpit/.

The common problem with BIND is trying to bind a port that is already in use. The trap is that there may not be an active socket, but the binding port (Bind return eaddrinuse) is still blocked, which is caused by the TCP socket state time_wait. This state is retained for approximately 2-4 minutes after the socket is closed. After the time_wait state exits, the socket is removed and the address can be rebind without problems.

Waiting for time_wait to end can be annoying, especially if you are developing a socket server, you need to stop the server to make some changes and reboot. Fortunately, there are ways to avoid the time_wait state. You can apply SO_REUSEADDR socket options to sockets so that the ports can be reused immediately.

Consider the example in Listing 3. Before binding the address, I invoke setsockopt with the SO_REUSEADDR option. To allow address reuse, I set the integer parameter (on) to 1 (otherwise, it can be set to 0来 prohibit address reuse).

In accordance with IBM's approach, I rewrote the SERVER.C code.

Server.c

  #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h > #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define BUFFER_SIZE int main () { Char Buf[buffer_size]; int SERVER_SOCKFD, CLIENT_SOCKFD; int sin_size=sizeof (struct sockaddr_in); struct sockaddr_in server_address; struct sockaddr_in client_address; memset (&server_address,0,sizeof (server_address)); server_address.sin_family = af_inet; SERVER_ADDRESS.SIN_ADDR.S_ADDR = Inaddr_any; Server_address.sin_port = htons (12000); Create a server-side socket if ((SERVER_SOCKFD = socket (af_inet, sock_stream, 0) <0) {perror ("SERVER_SOCKFD creation Failed"); Exi T (exit_failure); //Set socket option to avoid address using error int on=1; if (setsockopt (server_sockfd,sol_socket,so_reuseaddr,&on,sizeof (ON)) <0) {perror ("setsockopt failed"); Exit (Exit_failure); Bind the socket to the server's network address if (Bind (SERVER_SOCKFD, (struct sockaddr *) &server_address,sizeof (struct sockaddr)) <0) { PError ("Server socket bind failed"); Exit (Exit_failure); //Establish a listening queue listen (server_sockfd,5); Wait for the client connection request to reach client_sockfd=accept (SERVER_SOCKFD, struct sockaddr *) &client_address, (socklen_t*) &sin_size ); if (client_sockfd<0) {perror ("Accept client socket failed"); exit (exit_failure);}//Receive client data if (recv, buf,buffer_size,0) <0) {perror ("Recv client data Failed"); exit (exit_failure);} printf (Receive from client:%s/n BUF); Send data to Client if (send (CLIENT_SOCKFD, "I have received your message.", buffer_size,0) <0) {perror ("Send failed"); exit ( Exit_failure); Close (CLIENT_SOCKFD); Close (SERVER_SOCKFD); Exit (exit_success); }

       this time, let's start the server again and again,/server in the "Black Window"./server/server ... The server's program seems to suddenly become well-behaved, hehe, children's shoes, for their achievements to celebrate it ...

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.