Хранение информации о сокете, скорость произвольного доступа

#c #select #stl #map

#c #выберите #stl #словарь

Вопрос:

Текущая ситуация: у меня настроен сервер Linux (для общения с незнакомыми людьми), и у меня есть вопрос по эффективности.

В настоящее время я использую map в простом классе manager для объединения в пары двух незнакомцев:

 int sockManager::set_pair(int me, int them) {
 if (them != -1) {
    pairs[me] = them;
    pairs[them] = me;
    return 1;
 }
 return -1;
}
int sockManager::get_pair(int me) {
 return pairs[me];
}
void sockManager::add_single(int me) {
 pairs[me] = -1;
}
void sockManager::remove_single(int me) {
 if (pairs[me] != -1)
    pairs[pairs[me]] = -1;
 pairs.erase(me);
}
int sockManager::find_unconnected(int me) {
 if (pairs[me] != -1)
 return pairs[me];
 for (iter = pairs.begin();iter!=pairs.end();iter  ){
  if (iter->second == -1 amp;amp; iter->first != me)
  return iter->first;
 }
 return -1;
}
int sockManager::get_size(){
 return pairs.size();
}
  

Причина, по которой я использую этот класс manager, заключается в возможности расширения. Например, на данный момент я хочу изменить способ поиска двух клиентов для подключения. Я хотел бы иметь «необходимость подключения»
флаг и простой поток для постоянного просмотра и поиска клиентов для подключения, когда клиент не может быть подключен, если время прошло более x секунд, отправьте им забавную фразу или что-то еще (развлеките их) Мне также нужно убедиться, что клиент не подключается к кому-либо с тем же IP-адресом, что и у них…

Вот вопрос: я использую карту для хранения каждого сокета и соответствующего ему партнера. Существует ли другой, более быстрый способ хранения каждого сокета и комбинации партнеров? (для произвольного доступа, например, скорость поиска int [сокета] по сравнению с методом map.) {Моим первоначальным вопросом было использование массива структур для пар, затем я понял, что это было бы глупо… Файловые дескрипторы не увеличиваются на 1 каждый раз, поэтому было бы совершенно бесполезно думать, что массив ускорит процесс}

Субъективный (иш) вопрос: Я хотел бы сохранить флаги для каждого соединения, как вы думаете, лучшим и наиболее легко расширяемым методом было бы преобразовать значение (в отличие от ключа) пары map в структуру, содержащую необходимую информацию (партнерский сокет, флаг для подключения, флаг для …), или я должен создать другую карту с конкретными элементами флага в качестве значения? С памятью проблем не будет.

Третий, более основательный [amp; amp; немного не связанный] вопрос: я использую FD_Set с функцией select (), и я читал, что она довольно медленная при большом количестве FD (я знаю, что она может обрабатывать максимум 1024, но то же самое относится и к poll ()) Как бы мне реализовать систему, основанную на событиях, для прослушивания входящих данных от пользователей? (ОС: ubuntu Linux) и насколько быстрее это будет? Я провел стресс-тестирование своего сервера в его нынешнем виде, и я могу обрабатывать несколько сотен клиентов по сети без заметного замедления со стороны пользователя. Я хотел бы поддерживать более 3 тысяч одновременно.

Я понял больше, задав вопрос и поняв, сколько глупых вопросов я собирался задать, чем читая материал часами…

Ответ №1:

Как бы я реализовал систему, основанную на событиях, для прослушивания входящих данных от пользователей? (ОС: ubuntu Linux) и насколько быстрее это будет? Я провел стресс-тестирование своего сервера в его нынешнем виде, и я могу обрабатывать несколько сотен клиентов по сети без заметного замедления со стороны пользователя. Я хотел бы поддерживать более 3 тысяч одновременно.

Обычно люди, пытающиеся решить проблему c10k, будут использовать цикл обработки событий, предоставляемый libevent или MTasker. Использование потоков обычно позволяет достичь минимальных значений без особых хлопот, но в какой-то момент использование памяти становится очень ограниченным. Программирование на основе событий обычно позволяет серверам масштабироваться до тысяч, но это зависит от многих факторов.