2012-03-15 2 views
0

Я пытаюсь реализовать Window-сокет с помощью Python.Программирование оконных сокетов с 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 
     } 
    } 
} 

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

Для FD_ACCEPT, FD_READ, я мог бы найти их в win32file пакете (из pywin32 ОМТОВ)

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

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

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

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

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

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

+0

Если вы используете нулевой тайм-аут для 'select.select', то он не будет блокироваться. –

+0

@JoachimPileborg Спасибо: это сделало бы выбор не блокирующим. Однако для моей цели сервер по-прежнему блокирует основную программу, поскольку нам нужен цикл while вне select.select. Я отредактировал свой вопрос, чтобы уточнить мою цель. Благодарю. –

ответ

4

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

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

Это говорит, Python также имеет модуль для только что: SocketServer

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

сервер

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

Это немного трудно, чтобы помочь с так мало информации, но думать об этом так:

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

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

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

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

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

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

+0

Спасибо. Модуль сокета определенно хорош, но он блокирует основную программу, которая, похоже, не поддерживает потоки. В то время как 1: data = conn.recv (1024) ... В то время как 1 блок моей основной программы. –

+0

+1 Не изобретайте велосипед. –

+1

Установите блокировки, не блокирующие, если вы не хотите блокировать. И, конечно же, не используйте такой цикл while. –

2

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

Эквивалент в python будет, грубо говоря, вставить код «accept new conn» в том месте, где ваш код python принимает новое соединение. И вставьте код «получения данных» везде, где ваш код python получает данные.

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

+0

Спасибо. По вашему объяснению, похоже, что Async-сокет Window - это то, что мне действительно нужно. Есть ли способ реализовать его в Python? –

Смежные вопросы