How to completely destroy a socket connection in C

Harikrishnan picture Harikrishnan · May 16, 2012 · Viewed 71.4k times · Source

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?

Answer

SKi picture SKi · May 18, 2012

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.