![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| zss |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
создаю сокет
На этом сокете слушает сервер
На запросе сокет вываливает с ошибкой
Код ошибки 10035
Серверу приходит блок данных. Но перед ним идет заголовок. Он всегда одной длинны. В заголовке передается как правило длинна блока. Тоесть сначала сервер вычитывает заголовок. После определеяет длинну данных и вычитывает данные. Так вот если клиент отсылает все сразу, то тогда работает. А если он отсылает тоже кусками (тоесть сначала заголовок, а потом и блок), то сервер заголовок получает, а для того, чтоб получить данные ему приходится ждать (простейший Sleep(100) помог). Почему так ? З.Ы. И еще. событие FD_READ говорит о том, что серверу например пришел запрос. Тоесть поймав это событие можно обменивать данными. Когда сервер пытается отослать данные, то приходит FD_WRITE. Для чего это событие вообще нужно если через него можно определить лишь что сервер что-то пульнул в сокет |
||||||||
|
|||||||||
| Dude03 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 28.4.2006 Репутация: 1 Всего: 6 |
Насколько мне известно, то так заканчивается recv на асинхронном сокете, если нечего читать.
|
|||
|
||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
Dude03, да уменя так и есть - сокет неблокирующий. Но как реализовать ожидание новых событий FD_READ & FD_WRITE ?
|
|||
|
||||
| Dude03 |
|
||||||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 28.4.2006 Репутация: 1 Всего: 6 |
Асинхронная работа через объект события
Если в программе нет процедуры обработки сообщений, то можно воспользоваться объектами событий. В этом случае алгоритм работы будет несколько иной: Создать объект события с помощью функции WSACreateEvent. Выбрать сокет с помощью функции WSAEventSelect. Ожидать событие с помощью функции WSAWaitForMultipleEvents. Давайте подробно рассмотрим все функции, необходимые для работы с объектами событий. Первым делом следует создать событие с помощью функции WSACreateEvent. Функции не надо передавать никаких параметров, она просто возвращает новое событие типа WSAEVENT:
Теперь нужно связать сокет с этим объектом и указать события, которые нам нужны. Для этого используется функция WSAEventSelect:
Первый параметр — это сокет, события которого нас интересуют. Второй параметр — объект события. Последний параметр — это необходимые события. В качестве последнего параметра можно указывать те же константы, что рассматривались для функции WSAAsyncSelect (все они начинаются с префикса FD_). Раньше вы уже встречались с функциями WaitForSingleObject и WaitForMultipleObjects, которые ожидают наступления события типа HANDLE. Для сетевых событий используется похожая функция с именем WSAWaitForMultipleEvents:
Давайте рассмотрим каждый параметр: cEvents — количество объектов событий, изменение состояния которых нужно ожидать. Чтобы узнать максимальное число, воспользуйтесь константой WSA_MAXIMUM_WAIT_EVENTS; lphEvents — массив объектов событий, которые нужно ожидать; fWaitAll — режим ожидания событий. Если указано TRUE, то функция ожидает, пока все события не сработают, иначе — после первого передает управление программе; dwTimeOUT — временной интервал в миллисекундах, в течение которого нужно ожидать события. Если в этом временном интервале не возникло события, то функция возвращает значение WSA_WAIT_TIMEOUT. Если нужно ожидать бесконечно, то можно указать константу WSA_INFINITE; fAlertable — параметр используется при перекрестном вводе/выводе, который я не рассматриваю в этой книге, поэтому указан FALSE. Чтобы узнать, какое событие из массива событий сработало, нужно вычесть из возвращенного функцией WSAWaitForMultipleEvents значения константу WSA_WAIT_EVENT_0. Прежде чем вызывать функцию WSAWaitForMultipieEvents, все события в массиве должны быть пустыми. Если хотя бы одно из них будет занято, то функция сразу вернет управление программе, и не будет ожидания. После выполнения функции отработавшие события становятся занятыми, и после обработки их надо освободить. Для этого используется функция WSAResetEvent:
Функция очищает состояние события, указанного в качестве единственного параметра. Когда событие уже не нужно, его необходимо закрыть. Для этого используется функция WSACloseEvent. Функции следует передать объект события, который необходимо закрыть:
Если закрытие прошло успешно, то функция возвращает TRUE, иначе — FALSE. откуда-то=) Может не
а
Добавлено @ 15:30
А если у тебя с сокетом работает 2 потока и надо узнать когда другой что-то запишет туда? Это сообщение отредактировал(а) Dude03 - 28.1.2007, 15:27 |
||||||||||||||||
|
|||||||||||||||||
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
Dude03, спасибо за подробный ответ.
Но как все-таки ожидать. Может проще слушающий сокет сделать неблокирующим, а клиентскиу после WSAAccept блокирующим и для него запускать отдельный поток. А после того как поток отработал - убивать сокет. Но у меня почему-то после
клиент тоже оказывается неблокирующим. Почему ? |
|||
|
||||
| Dude03 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 28.4.2006 Репутация: 1 Всего: 6 |
Проще всего сделать через WSAAsyncSelect и сообщения Windows. Но там надо создать окно, которому и будет приходить сообщения.
|
|||
|
||||
| zss |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: нет Всего: 2 |
не - окна не пойдут - у меня сервис
а как это вообще может быть. Я кручу цикл и ловлю события. Как потоку сказать что для него (для сокета которым он владеет) пришли еще данные ? Добавлено @ 23:10 Я ведь могу только определить для какого сокета пришло событие |
||||
|
|||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |