I have made a chat client in linux using socket, and i wish to destroy the connection completely. Following is the relevant portions of the code:
int sock, connected, bytes_recieved , true = 1, pid; char send_data [1024] , recv_data[1024]; struct sockaddr_in server_addr,client_addr; int sin_size; label: if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Socket"); exit(1); } if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) { perror("Setsockopt"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(3128); server_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_addr.sin_zero),8); if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1) { perror("Unable to bind"); exit(1); } if (listen(sock, 5) == -1) { perror("Listen"); exit(1); } printf("\nTCPServer Waiting for client on port 3128"); fflush(stdout); connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size); //necessary code close(sock); goto label;
but the close(sock) doesnot seem to close the destroy the connection completely, because after going to 'label' the code is exiting showing the error message
Unable to bind: Address already in use
That is the connection is not happening again. What can the problem be? Thanks in advance.
EDIT: What I actually want is, when I run the script from the beginning after destroying the connection, it should run as a fresh program. How can I do it?
close() call shuts down the socket associated with the socket descriptor socket, and frees resources allocated to the socket. If socket refers to an open TCP connection, the connection is closed. If a stream socket is closed when there is input data queued, the TCP connection is reset rather than being cleanly closed.
The socket() function shall create an unbound socket in a communications domain, and return a file descriptor that can be used in later function calls that operate on sockets. The socket() function takes the following arguments: domain. Specifies the communications domain in which a socket is to be created.
If the socket is a TCP socket and it is connected, then the TCP connection will not be closed unless the socket is closed or shutdown() is called. Therefore, in this case, you should at least make sure to call shutdown() if you can't close the socket.
The close
call only marks the TCP socket closed. It is not usable by process anymore. But kernel may still hold some resources for a period (TIME_WAIT, 2MLS etc stuff).
Setting of SO_REUSEADDR should remove binding problems.
So be sure that value of true
is really non-zero when calling setsockopt
(overflow bug may overwrite it):
true = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int))
There is pid
variable is your code. If you use fork
(for starting connection handling processs), then you should close sock
also in the process which does not need it.
First for the naming, so we all name the same things the same:
Server side:
The socket passed to listen()
and then to accept()
let's call the listening socket. The socket returned by accept()
let's call the accepted socket.
Client side:
The socket passed to connect()
let's call the connecting/connected socket.
Regarding your issue:
To terminate the accept()
ed connection close the accepted socket (what you call connected) by optionally first using shutdown()
followed by close ()
.
To then accept a new connection loop right back before the call to accept()
, do not go via bind()
and listen()
again.
Only shutdown and close the listening socket if you want to get rid of pending connect()
s issued after accept()
returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With