Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.07.2008, 22:34   #11
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Цитата:
Сообщение от vynt Посмотреть сообщение
......а как определить что клиент отключился?
А как обычно. GetQueuedCompletionStatus либо вернёт ошибку, либо сообщит, что прочитано 0 байт. Дальше - GetLastError и по обстоятельствам...
B_N вне форума Ответить с цитированием
Старый 04.07.2008, 00:09   #12
vynt
Пользователь
 
Регистрация: 16.05.2008
Сообщений: 17
По умолчанию

GetQueuedCompletionStatus возвращает "истину"... а в dwBytesXfered всегда ноль.

Надо ли перезапускать WSARecv после сробатывания события? Я перезапускаю.
...тут я ещё не заполнял структуру WSABUF...

1. WSARecv если нет данных а клиент не отключился возвращает -1, полсе этого, вызов WSAGetLastError возвращает WSA_IO_PENDING (типа, ждите данных).
2. WSARecv если нет данных? а клиент отключился возвращает 0,
полсе этого, вызов WSAGetLastError возвращает тоже 0! и чего с этими нулями делать?...
3. Если данные пришли, но мало, и я не желаю их считывать то, опять таки имею два нуля

может существует функция вроде socketstatus? - нет - а хотелось бы
vynt вне форума Ответить с цитированием
Старый 04.07.2008, 11:31   #13
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

А. Главный поток.
1. Создаём completion port (далее с-порт) - CreateIoCompletionPort с параметрами по умолчанию.
2. создаём рабочий поток.
3. создаём overlapped сокет.
4. запускаем этот сокет - listen
5. "слушаем"
6. при поступлении коннекта копируем сокет - то, что вернула WSAAccept, создаём структуры данных для нового клиента, при этом не забываем про свою OVERLAPPED для каждого и прикручиваем этот "новый" сокет к с-порту через CreateIoCompletionPort - FileHandle - это "новый" сокет, ExistingCompletionPort - это наш изначальный c-порт, CompletionKey - адрес, например, нашей структуры.
7. Запускаем overlapped WSARecv. Буфер, естественно, указываем. ОС ведь должна куда-то поместить прочитанные данные.
8. возвращаемся к п. 5.

Б. Рабочий поток.
1. Ждём GetQueuedCompletionStatus. При этом предполагается, что параметры мы передали верные, в документации указано, что мы получим иначе.
2. Если ввод/вывод завершился с ошибкой то получаем 0 и выясняем что за ошибка - GetLastError, сколько байт получили и т.п. Если сокет "весь вышел", значит закрываем его, "выбрасываем" данные, которые выделялись для коннекта и т.п. и к пункту 1.
3. Если в/в успешный, то получаем не 0, читаем/записываем куда-нибудь/выбрасываем пришедшие данные, если нужно что-нибудь отправить клиенту, значит overlapped WSASend, если продолжаем читать, значит WSARecv.
возвращаемся к п. 1.

Если необходимо организовать связь главного потока с рабочим, скажем для остановки операций, значит из главного отправляем некий оговоренный статус через PostQueuedCompletionStatus или начинаем аккуратно закрывать сокеты. Выделенные для коннекта данные, пока они находятся "внутри" GetQueuedCompletionStatus трогать нельзя, освобождает их, например, рабочий поток после ошибки если сокет закрылся или даже деструктор класса клиента, если угодно.
B_N вне форума Ответить с цитированием
Старый 04.07.2008, 17:42   #14
vynt
Пользователь
 
Регистрация: 16.05.2008
Сообщений: 17
По умолчанию

Спасибо! Подробно
а что делать с хандлом созданым CreateIoCompletionPort, в конце, когда уничтожается рабочий поток CloseHandle()? просто про это нигде ничего не сказано...
для WSASend и WSARecv, каждому своя overlapped структура?
(проверять уже прийдётся не раньше чем через неделю. командировки в Питер и Новгород)
vynt вне форума Ответить с цитированием
Старый 05.07.2008, 11:54   #15
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Все ненужные хэндлы, естественно, закрываются через CloseHandle. Для каждого отдельного ввода и вывода должна быть своя overlapped, хотя после завершения в/в (именно с конкретной структурой) её (фактически, участок памяти) можно использовать заново. Если WSASend и WSARecv будут осуществляться одновременно, тогда у каждого должна быть своя, если строго по-очереди, то можно пользоваться одной (но, разумеется, в пределах данного сокета).
B_N вне форума Ответить с цитированием
Старый 13.07.2008, 20:47   #16
vynt
Пользователь
 
Регистрация: 16.05.2008
Сообщений: 17
По умолчанию

Хорошо...
А можно пользоваться одновременно и WSA и обычными функциями?
т.е. отправлять данные с помощью "send" а не "WSASend". мне допустим нужно отправлять данные пакетами асинхронно с приёмом, причём количество пакетов не известно и ждать завершения передачи "не хочеться" - когда освободится соответствующий буфер в overlapped структуре, не создовать же её для каждой процедуры передачи.
в 100 строк не укладываюсь.
Нужен ещё и тайм-аут для ожидания первого пакета клиента сразу после подключения, не пришлёт - отключить. Не тривиальная задачка то, получается
vynt вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите оценить, сколько может стоить проект. Его покупают - сколько взять? grenles Свободное общение 4 16.07.2008 09:38
Помогите подключиться к серверу. КривойПрограммист Помощь студентам 1 27.10.2007 23:41
Сервер и несколько клиентов Andr Работа с сетью в Delphi 10 17.09.2007 09:24
Как подключиться к серверу используя API функции? BR17UY Win Api 3 16.04.2007 02:12
Создать список клиентов банка Klyan Паскаль, Turbo Pascal, PascalABC.NET 3 15.01.2007 12:45