I developed a tcp server in c working on linux. I remarked that if I make a stress connections on the server (keep refreshing with "F5" the address of the server on my web browser), then my server will be freezed.
I checked the netstat
command, I found many socket opened on the server like this:
tcp 0 0 192.168.1.211:7547 192.168.1.133:10073 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9985 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9967 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10041 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10027 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10042 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10016 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9993 TIME_WAIT
In my server code I already close the sockets with close()
.
These socket are kept opened even if I close my server. And if I restart it againg , then bind()
return error (I think that because the sockets are not cleanly closed).
How to solve this problem?
How I can make my server not freezen even if there is a stress of connections?
How to force to be quicly closed in order to not get error in bind()
when restarting my server?
Code:
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<pthread.h> //for threading , link with lpthread
struct http_cr_data {
int client;
int count;
};
void *thread_serv_new_client(void *v)
{
int count;
int client;
struct http_cr_data *crd = (struct http_cr_data *)v;
count = crd->count;
client = crd->client;
free(crd);
printf("(%d) Received message by the server!\n", count);
close(client);
return NULL;
}
void server_init(void)
{
int socket_desc , client_sock , c, count=0 , *new_sock;
struct sockaddr_in server , client;
for(;;) {
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf ("Could not open server socket for Connection Requests, Trying again");
sleep(1);
continue;
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(7547);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
printf ("Could not bind server socket for Connection Requests, Trying again");
sleep(1);
continue;
}
break;
}
printf ("Connection Request server initiated");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
pthread_t serv_cr__thread;
struct http_cr_data *crd = malloc(sizeof (struct http_cr_data));
crd->count = ++count;
crd->client = client_sock;
int error = pthread_create(&serv_cr__thread, NULL, &thread_serv_new_client, (void *)crd);
if (error<0)
{
printf ("Error when creating Connection Request thread!");
}
}
if (client_sock < 0)
{
printf ("Could not accept connections for Connection Requests!");
return;
}
}
int main() {
server_init();
return 0;
}