Используя принимают () и выбор () одновременно?

У меня есть событийно-ориентированная программа сетевого сервера. Эта программа принимает соединения от других процессов на других хостах. Может быть много недолгих соединений от различных портов на том же удаленном IP.

В настоящее время у меня есть a while(1) цикл, который звонит accept() и затем порождает поток для обработки нового соединения. Каждое соединение закрывается после того, как сообщение прочитано. На удаленном конце закрывается соединение после того, как сообщение отправляется.

Я хочу устранить издержки соединений установки и разъединения путем кэширования открытого сокета FDs. На стороне отправителя это легко - я просто не закрываю соединения и имею в наличии их.

На стороне получателя это немного более твердо. Я знаю, что могу сохранить FD, возвращенный accept() в структуре и прислушиваются к сообщениям через все такое использование сокетов poll() или select(), но я хочу одновременно, оба прислушиваются к новым соединениям через accept() и послушайте на всех кэшируемых соединениях.

Если я использую два потока, один на poll() и один на accept(), затем, когда accept() назовите возвраты (новое соединение открыто), я должен разбудить другой поток, ожидающий на старом наборе соединений. Я знаю, что могу сделать это с сигналом и pselect(), но эта целая путаница походит слишком на большую работу для чего-то настолько простого.

Существует ли вызов или превосходящая методология, которая позволит мне одновременно обработать новые открываемые соединения и данные, отправляемые на старых соединениях?

20
задан Borealid 9 August 2010 в 22:39
поделиться

2 ответа

В прошлый раз, когда я проверял, вы могли просто прослушать на сокете, а затем выбрать или опрос , чтобы узнать, есть ли соединение вошел. Если так, примите его; он не будет блокироваться (но вы , возможно, захотите , на самом деле следует установить O_NONBLOCK, чтобы быть уверенным)

23
ответ дан 30 November 2019 в 00:43
поделиться

Я бы поместил слушателя в отдельный процесс (поток), чтобы не испортить ситуацию. И запустите рабочий процесс на другом для обработки существующих сокетов. На самом деле нет необходимости в неблокирующем слушателе. И никаких накладных расходов на потоки, выполняющих 2 потока.

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

Если вы хотите прослушивать несколько портов и не хотите удерживать один процесс для каждого прослушивателя, я предлагаю вам установить свой сокет в O_NONBLOCK и сделать что-нибудь вроде:

// loop through listeners here and poll'em for read, when read is successful call accept, get descriptor, pass it to worker and continue listen
    while(1){
        foreach( serverSocket in ServerSockets ){
             if( serverSocket.Poll( 10, SelectRead ) ){
                  clientSocket = serverSocket.Accept();
                  // pass to worker here and release
             }

        }
    }
0
ответ дан 30 November 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: