Программирование оконных сокетов с помощью Python - PullRequest
0 голосов
/ 15 марта 2012

Я пытаюсь реализовать сокет окна, используя Python.

В основном все было решено с помощью ctypes.windll.ws2_32 и pywin32 lib.

Однако я не смог выяснить, как перевести следующие коды C ++ в Python, и мне интересно, если кто-нибудь будет любезен помочь:

LRESULT WINAPI AsyncSocketProc(
                           __in  HWND hwnd,
                           __in  UINT uMsg,
                           __in  WPARAM wParam,
                           __in  LPARAM lParam
                          )
switch(uMsg) {
    case WM_CREATE: 
        //...
    case WM_SOCKET: {# this is basically an int constant
        switch(WSAGETSELECTEVENT(lParam)){
              case FD_ACCEPT:
                  //accepting new conn
              case FD_READ:
                  //receiving data 
        }
    }
}

В приведенном выше коде я не смог найти эквивалент Python для WSAGETSELECTEVENT.

Для FD_ACCEPT, FD_READ, я могу найти их в пакете win32file (из pywin32 lib)

Наконец, причина, по которой я пытаюсь реализовать это программирование сокетов Windows, заключается в том, что версия сервера сокетов окон C ++ (выше) не блокирует мое приложение, а встроенный в Python select.select блокирует , Поэтому я пытаюсь выяснить, могу ли я перенести версию C ++ на Python и посмотреть, работает ли она.

Редакция: Я хотел бы уточнить, что сервер сокетов работает как «плагин» для существующей программы C ++ , , которая не поддерживает многопоточность .

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

Каким-то образом при использовании обратного вызова сервера Window Socket выше основная программа не блокируется. И это главная причина, пока я пытаюсь перенести его на Python.

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

Большое спасибо.

Ответы [ 2 ]

4 голосов
/ 15 марта 2012

Взгляните на модуль гнезда . Он уже содержит весь код, необходимый для работы с сокетами без использования win32 API.

[EDIT] Вы можете написать многопоточный код, который может обрабатывать несколько соединений. Просто примите соединение и затем запустите новый поток, дайте ему соединение и дайте ему читать данные в виде while 1: data = conn.recv(1024) ... цикла.

Тем не менее, Python также имеет модуль для этого: SocketServer

[EDIT2] Вы говорите

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

Немного трудно справиться с таким небольшим количеством информации, но подумайте об этом следующим образом:

Вы можете запустить цикл сервера сокетов в новом потоке. Этот код изолирован от остальной части вашего приложения, поэтому не имеет значения, использует ли другой код / ​​поддерживает потоки. Это решает вашу проблему с "бесконечной петлей".

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

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

Но если я вас правильно понимаю, вы можете изменить «основной цикл» существующего приложения и позволить ему делать больше вещей (например, прослушивать новые соединения). Если вы можете сделать это, то есть выход:

Создайте новый поток для сервера сокетов, как описано выше. Когда сервер получает соединение, создайте новый поток, который общается с клиентом. Когда клиент отправляет команды, создайте «рабочие объекты» (см. шаблон команды ) и поместите их в очередь .

.

В основном цикле вы можете заглянуть в очередь. Если что-то есть, вытолкните рабочие объекты и вызовите метод run().

2 голосов
/ 15 марта 2012

Вам не нужно или вы не хотите портировать этот код.Этот код зависит от того, как WIN32 API уведомляет собственный код о завершении операции с сокетом.Это не применимо в Python.

Эквивалентом в python будет, примерно, вставка кода «принимающий новый conn» туда, где ваш код питона принимает новое соединение.И вставляйте код «получения данных» туда, куда ваш код Python получает данные.

Вы также можете использовать select , просто имейте в виду, что семантика немного отличается от асинхронных сокетов.С асинхронными сокетами вы запускаете операцию, когда хотите, и получаете ответный вызов, когда она завершается.С помощью «select» он сообщает, когда выполнить операцию, чтобы она немедленно завершилась.

...