Too many open files open and close when starting an infinite socket

I searched all about this question on this site.

my programming scenario:

  • There is one server that always listens for a request from a client.
  • there is one client that always requests char from the server in 2 seconds

get error message:

Too many open files "occurred in the socket () function after starting the program about 1024 times.

My current solution is to increase the number of open files: "ulimit -n 5000" , but I do not think this is the ideal solution, because it will make the program work 5000 times.

So, does anyone have a better solution?

Environment:

  • ubuntu 10
  • c language

My code is as follows:

Customer:

  int sockfd; struct sockaddr_in address; int socket_port = 9734; while (1) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) DieWithSystemMessage("socket() failed");//<<===========Too many open files memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("127.0.0.1"); address.sin_port = socket_port; //Establish the connection to the server if ((connect(sockfd, (struct sockaddr *) &address, sizeof(address))) < 0) DieWithSystemMessage("connect() failed"); if (rename_count % 2 == 0) ch = 'A'; else if (rename_count % 2 == 1) ch = 'B'; else ch = 'E'; ssize_t numBytes = send(sockfd, &ch, strlen(&ch), 0); if (numBytes < 0) DieWithSystemMessage("send() failed"); else if (numBytes != strlen(&ch)) DieWithUserMessage("send()", "sent unexpected number of bytes"); //fflush(sockfd); shutdown(sockfd, SHUT_RDWR); rename_count++; } 

Server:

 int server_sockfd, client_sockfd; int server_len, client_len; socklen_t clntAddrLen; struct sockaddr_in server_address; struct sockaddr_in client_address; uint64_t start_time_micro, end_time_micro; int socket_num = 9734; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); if (server_sockfd < 0) DieWithSystemMessage("socket() failed"); memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = socket_num; if ((bind(server_sockfd, (struct sockaddr *) &server_address, sizeof(server_address))) < 0) DieWithSystemMessage("bind() failed"); if ((listen(server_sockfd, 5)) < 0) DieWithSystemMessage("listen() failed"); while (1) { char ch; printf("\nserver waiting\n"); //accept a connect clntAddrLen = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_address, &clntAddrLen); if (client_sockfd < 0) DieWithSystemMessage("accept() failed"); //reading and writing through client side ssize_t numBytesRcvd = recv(client_sockfd, &ch, 1, 0); if (numBytesRcvd < 0) DieWithSystemMessage("recv() failed"); if (ch == 'A') { rename_num = 0;//printf("A\n"); } else if (ch == 'B') { rename_num = 1;//printf("B\n"); } else ; printf("%d. Got it!!!\n", i); close(client_sockfd); } close(server_sockfd); 
+4
source share
2 answers

You close the socket in the client, but do not close it. This is not the same.

+3
source

There is a big difference between shutdown() and close() . When you “complete” a socket, you put it in a “half-closed” state, where you can still send or receive (depending on which half you turn off) the connection.

The socket is still valid, TCP still stores connection status information, and the port is still “open”, and the socket / file descriptor is still allocated to your process.

When you call close() , the socket / file descriptor is free , but the rest remains . TCP should contain resources for some time, usually 2 minutes (it depends on who made the closure and some other things), during which the status information and the local port itself are still "used".

Thus, even if you can no longer exceed the file descriptor limit for your process, it is theoretically possible to fill the resources of the network stack and not be able to open a new connection.

+3
source

Source: https://habr.com/ru/post/1443636/


All Articles