Nano Hash - криптовалюты, майнинг, программирование

Слишком много открытых файлов, когда я запускаю бесконечный сокет, открытый и закрытый

Я искал все об этом вопросе на этом сайте.

мой сценарий программы:

  • есть один сервер, который всегда слушает запрос от клиента.
  • есть один клиент, который всегда запрашивает char с сервера каждые 2 секунды

получить сообщение об ошибке:

Слишком много открытых файлов" произошло в функции socket() после запуска программы около 1024 раз.

Мое текущее решение состоит в том, чтобы увеличить количество открытых файлов: "ulimit -n 5000", но я не думаю, что это идеальное решение, потому что это заставит программу запускаться 5000 раз.

Итак, есть ли у кого-нибудь лучшее решение?

Окружающая обстановка:

  • убунту 10
  • c язык

Мой код выглядит следующим образом:

Клиент:

    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++;

}

Сервер:

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);
02.11.2012

  • Возможно, вы захотите заменить strlen(&ch) на 1 (2 раза в клиентском коде). 02.11.2012
  • да, моя проблема ясна. мое резюме таково: слишком много ошибок открытых файлов вызвано тем, что вы открываете много файловых дескрипторов и неправильно освобождаете файловые дескрипторы. 06.11.2012

Ответы:


1

Вы закрываете сокет в клиенте, но никогда его не закрываете. Это не то же самое.

02.11.2012

2

Между shutdown() и close() есть большая разница. Когда вы «выключаете» сокет, вы переводите его в «полузакрытое» состояние, когда по соединению все еще можно отправлять или получать (в зависимости от того, какую половину вы закрыли).

Сокет по-прежнему действителен, TCP по-прежнему поддерживает информацию о состоянии соединения, а порт по-прежнему «открыт», а дескриптор сокета/файла по-прежнему выделен вашему процессу.

Когда вы вызываете close(), дескриптор сокета/файла освобождается, но остальное остается. TCP должен удерживать ресурсы в течение некоторого времени, обычно 2 минуты (это зависит от того, кто сделал закрытие и некоторые другие вещи), в течение которых информация о состоянии и сам локальный порт все еще «используются».

Таким образом, даже если вы больше не можете превышать ограничение файлового дескриптора для вашего процесса, теоретически возможно насытить ресурсы сетевого стека и по-прежнему не иметь возможности открыть новое соединение.

02.11.2012
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..