Write a simple socket network communication program today, after using CTRL + C to end the server-side program, start the server again there is a bind failed:the address already in the error. After checking the Internet, I found out the reason, here to record a bit. This is what IBM's official web site says: http://www.ibm.com/developerworks/cn/linux/l-sockpit/. Detailed descriptions are as follows:
< Span style= "line-height:1.5em" >bind The common problem is trying to bind a port that is already in use. The trap is that there may not be an active socket, but it is still forbidden to bind the port ( bi nd return EA Ddrinuse ), which is time_wait caused. The status is retained for approximately 2-4 minutes after the socket is closed. In time_wait After exiting, the socket is deleted and the address can be re-bound without problems.
wait time_wait End may be an annoying thing , especially if you are developing a socket server, you will need to stop the server to make some changes and then reboot. Fortunately, there are ways to avoid time_wait status. You can apply so_reuseaddr socket options so that the ports can be reused immediately.
Consider the example in Listing 3. Before binding the address, I call setsockoptwith the so_reuseaddr option. To allow address reuse, I set the integer parameter (on) to 1 (otherwise, it can be set to zero address reuse).
Listing 3. Use SO_REUSEADDR socket option to avoid address usage errors
int sock, ret, on;struct sockaddr_in servaddr;/* Create A new stream (TCP) Socket */sock =Socket(Af_inet, Sock_stream, 0):/* Enable address reuse */On = 1;ret = setsockopt(sock, Sol_socket, so_reuseaddr, &on, sizeof (on));/* Allow connections to port 8080 from any available interface */memset (&servaddr, 0, sizeof (SERVADDR)); Servaddr.sin _family = AF_INET;SERVADDR.SIN_ADDR.S_ADDR =htonl(inaddr_any); servaddr.sin_port =htons(45000);/* Bind to the address (interface/port) */ret =Bind(sock, (struct sockaddr *) &servaddr, sizeof (SERVADDR));
After the so_reuseaddr option is applied, thebind API function will allow immediate reuse of the address.
I followed the instructions above to add this code after an error occurred: setsockopt failed:socket operation on Non-socket.
And then on the Internet,Socket operation on Non-socket error occurs in two cases:
1. Create socket:
if (listenfd= socket (af_inet,sock_stream, 0) ==-1) {
Perror ("Creating Socket failed!");
Exit (-1);
}
Causes Socket operation on Non-socket error when bind occurs
The correct code should be:
if ((LISTENFD = socket (af_inet, sock_stream, 0)) = = = 1) {
Perror ("Creating Socket failed!");
Exit (-1);
}
2. When you accept:
if (Connfd=accept (LISTENFD, (struct sockaddr *) &client_addr, (socklen_t *) &sin_size) ==-1) {
Perror ("Accept error!");
Exit (-1);
}
Causes Socket operation on Non-socket error when recv
The correct code is:
if ((Connfd=accept (LISTENFD, (struct sockaddr *) &client_addr, (socklen_t *) &sin_size)) (==-1) {
Perror ("Accept error!");
Exit (-1);
}
The socket operation on Non-socket error occurs because:
if (listenfd= socket (af_inet,sock_stream, 0) ==-1)
if (Connfd=accept (LISTENFD, (struct sockaddr *) &client_addr, (socklen_t *) &sin_size) ==-1)
The two sentences are missing (). Assignment accords with the lowest priority, causing LISTENFD and connfd to be 0 when the creation/connection succeeds and 1 when unsuccessful
finally:
If you call the Connect socket accept function error, you can perror ("socket"); Perror ("Connect"); printf ("%s\n", Strerror (errno)) can make specific mistakes.
The compilation result has the following error: undefined reference to ' pthread_create ', should be added-lpthread parameters in the compilation.