В разделе 7.2 руководства Биджа описан способ сделать это, который сначала изучают большинство программистов на Си. Пример в конце раздела 7.2 должен быть именно тем, что вы хотите.
По сути, вы используете select
, чтобы позволить вашей программе ожидать получения данных по одному из уже принятых соединений или попытки подключения нового клиента. Затем вы проверяете, что произошло, и справляетесь с этим. (К сожалению, пример учит одну плохую привычку - он забывает установить сокеты в неблокирующий режим, поэтому он может зайти в тупик в accept
, если соединение больше не находится в состоянии ожидания.)
Основная идея такова:
1) Настройте базовые структуры для отслеживания клиентов, инициализируйте их, чтобы отразить тот факт, что у вас нет клиентов.
2) Настройте гнездо прослушивания для новых подключений.
3) Подождите, пока что-то произойдет, используя select
. Можно дождаться подключения нового клиента, данных, которые будут получены от существующего клиента, данных, которые можно будет отправить существующему клиенту, ошибки, возникшей в существующем соединении, или определенного количества времени для прохождения. Используйте структуры, которые отслеживают ваших клиентов, чтобы убедиться, что вы ждете получения данных от всех ваших существующих клиентов.
4) Обращайся, что бы ни случилось. Если новый клиент пытается подключиться, accept
подключите и обновите структуры отслеживания. Если данные были получены от клиента, посмотрите, завершает ли он команду, и, если это так, обработайте ее. Если один из ваших клиентов закрыл соединение или произошла ошибка в этом соединении, очистите его, закрыв сокет и обновив отслеживание.
5) Вернитесь к шагу 3.
Это называется «мультиплексирование ввода / вывода». Есть и другие способы сделать это, но именно так большинство программистов на С сначала учатся.