Принять подключение к гнезду прослушивания на сокете прослушивания (и больше не прослушивать)? - PullRequest
3 голосов
/ 18 октября 2011

Я занимаюсь программированием сокетов в Delphi 6 Pro с использованием библиотеки ICS (TWSocket).Я знаю, что мой вопрос может показаться либо запутанным, либо неуклюжим, но позвольте мне объяснить потребности моего приложения, чтобы вы поняли, почему я хочу сделать что-то, что противоречит обычному соглашению, используемому с прослушивающим сокетом, - выделению входящего соединения к новому сокету.возвращается методом Accept и продолжает прослушивать новые соединения на текущем установленном порту.

В моем приложении я принимаю соединения от Skype для отправки и получения аудиобуферов, связанных с активным вызовом Skype.Проблема заключается в том, что при подключении к Skype нет подтверждения связи, идентификации или аутентификации, которые позволили бы мне узнать, для какого CALL ID предназначено соединение.Поскольку Skype может выполнять конференц-вызовы вместе, может быть несколько активных вызовов одновременно.Однако мне нужно знать, какие сокетные соединения принадлежат какому CALL ID.

Поскольку соединение является «слепым» соединением, как указано выше, единственный способ надежно сопоставить соединения сокетов Skype с идентификаторами CALL ID - это тщательно контролировать номер порта, который я слушаю.Затем, когда я говорю Skype, чтобы он подключил аудио для данного идентификатора CALL к определенному номеру порта, я знаю, что соединение, входящее в этот сокет, принадлежит этому идентификатору CALL Skype.Например:

  1. Найти номер доступного порта, iPortNumber .
  2. Установить мой сокет для прослушивания iPortNumber
  3. Скажите Skype, чтобы он подключил CALL ID iCallID к номеру ПОРТА iPortNumber
  4. Когда я получаю событие SessionAvailable, я знаю, что входящее соединение Skype для CALL ID iCallID .

Сполосните и повторите для каждого идентификатора CALL ID, который мне нужно обработать.Я знаю, что это означает, что я мог бы в конечном итоге жевать несколько дополнительных портов, но так как количество одновременных звонков в Skype всегда мало, я не вижу в этом проблемы.С чем я сталкиваюсь, так это со стандартным соглашением о наличии сокета Listening, который раскручивает новый сокет с помощью Accept при входе в новое соединение.

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

Альтернативным способом было бы использовать вновь созданный сокет, возвращаемый Accept, а затем закрыть сокет Listening, но тогда мне нужно придумать более сложный метод для отслеживания порта.номера для идентификаторов CALL Skype, потому что, если я правильно знаю, только что созданный сокет, возвращенный Accept, подключен к другому номеру порта, чем к гнезду Listening, поэтому сокет Listening может продолжать прослушивать существующий номер порта.Я хотел бы избежать этой дополнительной сложности и хлопот, если бы мог.

Если у кого-то есть лучшая общая идея / парадигма о том, как сопоставить мои слепые соединения Skype с привязанными к ним идентификаторами Skype CALL, пожалуйста,дай мне знать.Кроме того, я не думаю, что это возможно, но если есть умный способ получить идентификатор процесса за входящим соединением Socket от процесса, подключенного к той же системе, что и мое приложение, я хотел бы знать.

1 Ответ

3 голосов
/ 19 октября 2011

Одноразовые розетки для прослушивания не так уж и необычны. Протокол FTP использует их, например. Просто создайте новый прослушивающий сокет на желаемом порте (или позвольте сокету выбрать свой собственный порт, который вы затем сможете извлечь), установите для своего backlog значение 1, затем вызовите accept() для него только один раз и закройте его. Если accept() принимает клиентское соединение, он возвращает новый дескриптор сокета, который вы используете для связи с этим клиентом. Вам не нужно поддерживать розетку для прослушивания в течение этого времени.

Я не знаю, каким будет ICS-эквивалент этой операции, но в Indy для этой цели есть компонент TIdSimpleServer (кстати, Skype в Windows использует Indy).

...