2016-06-01 3 views
0

У меня есть простой сервер с именем трубы, реализованный в питона + ctypes:ERROR_NO_MORE_ITEMS с именем трубы и завершения ввода-вывода порта

pipe = windll.kernel32.CreateNamedPipeA('\\\\.\\pipe\\pipe_name', PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 0, 0, 0, None) 

overlapped_struct = OVERLAPPED() 

windll.kernel32.ConnectNamedPipe(pipe, byref(overlapped_struct)) 

iocp = windll.kernel32.CreateIoCompletionPort(pipe, None, WPARAM(707070707), 0) 

while True: 
    bytes_transferred = DWORD() 
    completion_key = WPARAM() 
    overlapped_struct_ptr = POINTER(OVERLAPPED)() 
    windll.kernel32.GetQueuedCompletionStatus(iocp, byref(bytes_transferred), byref(completion_key), byref(overlapped_struct_ptr), INFINITE) 

    bytes_available = DWORD() 
    windll.kernel32.PeekNamedPipe(pipe, None, 0, None, byref(bytes_available)) 

    buf = create_string_buffer(bytes_available.value) 
    ret_code = windll.kernel32.ReadFile(pipe, byref(buf), bytes_available.value, None, overlapped_struct_ptr) 

Он получает данные из внешней программы. Я ожидаю, что GetQueuedCompletionStatus вернется только тогда, когда что-то придет к трубе, но это не всегда так. Иногда, после того, как он завершает пакет завершения, я вижу, что bytes_available == 0, ret_code == 0 и overlapped_struct.Internal == 256 (что я предполагаю, что это означает ERROR_NO_MORE_ITEMS).

Любые идеи о том, почему это происходит?

+0

Вы используете 64-битный Python? Попробуйте указать '.argtypes' для всех своих функций, чтобы гарантировать, что элементы правильно настроены на C. –

ответ

0

Я понял. Пакет завершения ставится в очередь после любой операции на трубе. Это означает, что GetQueuedCompletionStatus вернется после подключения клиента, операции записи и чтения.

Что происходит в моей ситуации:

  1. я получил данные из внешней программы. Пакет завершения был поставлен в очередь.
  2. Я читал трубку. Другой пакет завершения был поставлен в очередь.
  3. Во время последующего чтения, если в трубе не было новых данных, ReadFile возвращено 0 и overlapped_struct.Internal указано ERROR_NO_MORE_ITEMS, что совершенно верно: новых данных в трубе не было.