Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to completely destroy a socket connection in C

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?

like image 201
Harikrishnan Avatar asked May 16 '12 13:05

Harikrishnan


People also ask

How do I remove a socket connection?

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.

What does socket () do in C?

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.

Do you need to close socket C?

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.


2 Answers

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.

like image 158
SKi Avatar answered Sep 19 '22 09:09

SKi


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.

like image 39
alk Avatar answered Sep 22 '22 09:09

alk