Я написал сервер и клиент, которые используют перекрывающийся именованный канал.Моя проблема в основном с Readfile () и GetOverlappedResult ().
Обратите внимание, что эта программа является тестовым кодом.Позже он будет интегрирован в среду (я портирую код linux на unix, который использует семейство адресов AF_UNIX для соединений с сокетами)
Я описываю серверную часть.У меня есть 2 потока:
1) основной поток открывает перекрывающийся именованный канал, затем зацикливается на WaitForMultipleObjects ().WaitForMultipleObjects () ожидает 3 события: первое ожидает подключения клиента.2-й позволяет мне чисто выйти из программы.Третий сигнализируется, когда операция ожидает в ReadFile ().
2) Второй поток запускается при подключении клиента.Он зацикливается на ReadFile ().
Вот код сервера:
http://pastebin.com/5rka7dK7
Я в основном использовал MSDN doc (именованный канал-сервер с использованием перекрывающегося ввода-вывода, названныйтруба клиента), SDK и другие документы в Интернете, чтобы написать этот код.Посмотрите в [1] код клиента.Код клиента нуждается в некоторой любви, но сейчас я сосредоточен на том, чтобы сервер работал идеально.
В коде сервера есть 4 функции (я забыл функцию, которая отображает сообщения об ошибках):
a) svr_new: он создает перекрывающийся именованный канал и 3 события и вызывает ConnectNamedPipe ()
b) svr_del освобождает все ресурсы
c) _read_data_cb: поток, вызывающий ReadFile ()
d) функция main () (основной поток), которая зацикливается на WaitForMultipleObjects ()
Моя цель - обнаружить в _read_data_cb (), когда клиент отключается (сбой ReadFile ()и GetLastError () возвращает ERROR_BROKEN_PIPE) и когда данные поступают от клиента.
Что я не понимаю:
- Должен ли я вызывать GetOverlappedResult ()?
- Если да, то где?Когда ReadFile () завершается неудачно и GetLastError () возвращает ERROR_IO_PENDING (строка 50 вставки)?Когда WaitForMultipleObjects () возвращает (строка 303 вставки, я прокомментировал код там)?Где-то еще?
- Я делаю ResetEvent события ReadFile (), когда WaitForMultipleObjects () возвращает (строка 302 вставки).Это правильное место для его вызова?
С кодом, который я вставил, вот результат, если клиент отправляет эти 24 байта (буфер ReadFile () имеет размер 5 байтов. Я намеренно установилэто значение, чтобы проверить, что делать, если клиент отправляет некоторые данные, превышающие размер буфера ReadFile ()
: «salut, c'est le client!»
output:
$ ./server.exe ожидает клиента ... WaitForMultipleObjects: 0 клиент подключен (1) WaitForMultipleObjects: 2 * ReadFile: 5 WaitForMultipleObjects: 2 * ReadFile: 5 WaitForMultipleObjects: 2 * ReadFile: 5 WaitForMultipleObjects: 2 * ReadFile5 WaitForMultipleObjects: 2 * ReadFile: 4
Примечание: WaitForMultipleObjects () может быть вызвано меньше, чем это кажется случайным.
Итак, в моем коде я не вызываю getOverlappedResult (),ReadFile () завершается успешно (il читает 5 * 4 + 4 = 24 байта), но я не знаю, когда операция чтения завершится.
Примечание: я добавляю printf (), когда ReadFile () завершается неудачно сERROR_IO_PВ завершение, этот printf () вызывается бесконечно.
Кроме того, клиент отправляет 2 сообщения.Один выше, а другой через 3 секунды.2-е сообщение никогда не читается и ReadFile () завершается с ошибкой ERROR_SUCCESS ... (если быть точным, ReadFile () возвращает FALSE, а GetLastError () возвращает ERROR_SUCCESS)
Итак, я полностью потерян.Я искал часы в Интернете, в MSDN, в коде SDK (Server32.c и Client32.c).Я до сих пор не знаю, что делать в моем конкретном случае.
Итак, кто-то объяснит мне, как использовать GetOverlappedResult () (если я должен его использовать), чтобы узнать, как проверить, завершена ли операция чтения и где?И даже, если кто-то может исправить мой код :-) Я дал код, чтобы каждый мог его протестировать (я нахожу много документов в интернете, но это почти всегда не точно:* спасибо
[1] http://pastebin.com/fbCH2By8