Я использую клиент-серверное приложение TCP-сокета. Client
на маршрутизаторе OpenWRT Linux (на основе C) и несколько раз записывает данные в сокет и в al oop с некоторой частотой. Server
находится на машине Linux Ubuntu (на основе C / C ++) и считывает данные в al oop в соответствии со скоростью поступления данных.
Проблема : Запуск Server
а затем Client
, сервер продолжает читать новые данные. Обе стороны работают хорошо, пока количество доставленных данных (число соединений) не достигнет 1013. После этого Client
застрял на socket(AF_INET,SOCK_STREAM,0)
с socket creation failed...: Too many open files
. По-видимому, число открытых fd
приближается к ulimit -n = 1024
на клиенте.
Я поместил фрагменты кода, который показывает структуры l oop для Server.cpp
и Client.c
:
Сервер. c:
// TCP Socket creation stuff over here (work as they should):
// int sock_ = socket() / bind() / listen()
while (1)
{
socklen_t sizeOfserv_addr = sizeof(serv_addr_);
fd_set set;
struct timeval timeout;
int connfd_;
FD_ZERO(&set);
FD_SET(sock_, &set);
timeout.tv_sec = 10;
timeout.tv_usec = 0;
int rv_ = select(sock_ + 1, &set, NULL, NULL, &timeout);
if(rv_ == -1){
perror("select");
return 1;
}
else if(rv_ == 0){
printf("Client disconnected.."); /* a timeout occured */
close (connfd_);
close (sock_);
}
else{
connfd_ = accept (sock_,(struct sockaddr*)&serv_addr_,(socklen_t*)&sizeOfserv_addr);
if (connfd_ >= 0) {
int ret = read (connfd_, &payload, sizeof(payload)); /* some payload */
if (ret > 0)
printf("Received %d bytes !\n", ret);
close (connfd_); /* Keep parent socket open (sock_) */
}else{
printf("Server acccept failed..\n");
close (connfd_);
close (stcp.sock_);
return 0;
}
}
}
Клиент. cpp:
while (payload_exist) /* assuming payload_exist is true */
{
struct sockaddr_in servaddr;
int sock;
if (sock = socket(AF_INET, SOCK_STREAM, 0) == -1)
perror("socket creation failed...\n");
int one = 1;
int idletime = 2;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &idletime, sizeof(idletime));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.100.12");
servaddr.sin_port = htons(PORT); /* some PORT */
if (connect (sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0){
perror("connect failed...");
return 1;
}
write(sock, (struct sockaddr*)&payload, sizeof(payload)); /* some new payload */
shutdown(sock,SHUT_WR);
bool serverOff = false;
while (!serverOff){
if(read(sock, &res, sizeof(res)) < 0){
serverOff = true;
close(sock);
}
}
}
ПРИМЕЧАНИЕ : payload
равен 800 bytes
и всегда получает полностью передается за одно write
действие. Имея оба кода, определенные в int main()
, клиент продолжает создавать сокеты и отправлять данные, с другой стороны, сервер получает все и автоматически close()
и уходит, если клиент завершает работу из-за использования select()
. Однако если я не завершу работу Client
, проверив некоторые журналы печати, очевидно, что Server
успешно получит 1013 полезных данных, прежде чем произойдет сбой клиента с socket creation failed...: Too many open files
.
Обновление :
Следуя пункту, упомянутому Штеффеном Ульрихом, выяснилось, что у клиентского сокета fd
нет утечки, и существует второй fd
в исходном l oop (который был оставил открытым) заставлял ulimit
превышать лимит.