![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
Всем добрый день!
Передо мной поставили задачу написать клиент-серверное приложение, обменивающиеся данными через интернет. Есть клиентское приложение, которое отправляет на сервер текстовые сообщения, являющиеся по сути командами, а также графику (bmp, jpg, gif). Сервер получает данную строку и формирует из нее SQL запрос, данный запрос отправляется базе MySQL, которая отрабатывает данный запрос и возвращает данные, которые переправляются обратно клиенту. Клиент их визуализирует. Примерное количество клиентов, которые будут подключаться к серверу равно 1000 (это примерно). Пишу на с++ Builder 2009. Сначала я думал писать при помощи Indy, но ребята меня переубедили, что этого не стоит делать, а лучше написать транспортный модуль самому. Под транспортным модулем я подразумеваю не новый протокол обмена данными по сети, а так сказать интерфейс работающий с TCP/IP протоколом. Почитав литературу и порывшись на сайтах, нашел много информации и методов работы с TCP/IP, НО НА КАКОМ ОСТАНОВИТЬСЯ не знаю. Поэтому и прошу у Вас помощи. Вот основные методы для работы с TCP/IP протоколом: 1. Блокирующий(синхронный) сокет. 2. Не блокирующий (асинхронный) сокет. Для нормальной работы первого метода, создаются потоки, при подключении нового клиента к серверу. Как мне кажется плюс этого метода, что одна на писаная функция работы с клиентом и каждый раз запускаемая в потоке решает все задачи, которые я пропишу. Но вопрос, не накладно ли будет для железа создавать 1000 потоков, разгребет ли, и есть ли смысл и целесообразно ли? Но есть и большой минус. Допустим, что был вызов функции recv, но по каким-то причинам она не вернула данные. В этом случае она останется заблокированной навечно, и сервер больше не будет реагировать на действия пользователя. Второй метод более гибкий, но он и труднее в программировании и лишен выше описанной проблемы. Для асинхронных соке тов так же можно выделить несколько методов: 1. Использование массива соке тов и с использованием select 2. Использование соке тов через события windows 3. Асинхронная работа через объекты событий. Описывать +/- каждого метода долго. Но вся проблема, для меня, упирается в то, как использовать асинхронные сокеты 2 и 3 для 1000 подключенных, как отслеживать, от кого пришла стока и кому ответить (для всех трех методов). И ко всему этому остается проблема правильности доставки сообщений, не факт, и это известно, что данные придут сразу все. Могут придти не все, а если сообщения маленькие, то они могут придти сразу оба. Как при использовании асинхронного сокета учесть это и при синхронном тоже? Надеюсь не утомил. ![]() Очень нужна помощь, направьте на путь истинный! ![]() Заранее спасибо. -------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
не изобретайте велосипед
используете паттерн реактор кол-во потоков = кол-во ядер * 2 для винды используете completion ports, для *nix - пулы - если есть, select - если пулов нет - оптимально можно заюзать boost::asio - там использование этих фич скрыто в классах |
|||
|
||||
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
J0ker, можно подробнее. Много "красивых" слов. Но пока они мне не все понятны.
![]() -------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
Cтpaнник |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 12.10.2008 Где: Россия, Санкт-Пет ербург Репутация: нет Всего: нет |
||||
|
||||
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
Cтpaнник, не могу с этого сайта ничего скачать. Можешь скинуть скаченные архивы, благо они весят не много. + ссылочку на описание IOCP. не могу найти русскоязычного описания! Заранее спасибо!
-------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
||||
|
||||
Cтpaнник |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 53 Регистрация: 12.10.2008 Где: Россия, Санкт-Пет ербург Репутация: нет Всего: нет |
vikaz, там чтобы что-то скачивать (архивы, примеры и т.п.) просто надо зарегистрироваться. Это бесплатно
![]() |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
паттерн многопоточный реактор - создаете пул потоков которые сидят на ожидании (лучше организовать LIFO) в случае пулов и completion ports - когда приходит сообщение первый свободный поток из очереди его подхватывает и вызывает соответствующий обработчик в случае использования select - диспетчер подхватывает сообщение, и соответственно типу передает его потоку инициализированному конкретным обработчиком по поводу кол-ва потоков в пуле обычно бессмысленно держать в работе больше потоков, чем имеется ядер но учитывая особенности например completion ports, надо иметь под рукой запасные потоки, т.к. при попадании работающего потока в операцию, вызывающую какую-либо wait функцию, система считает, что можно запустить еще один поток. т.о. все зависит от того, что делает обработчик - если это голые вычисления, допустим, где гарантированно нет wait вызовов, то можно ограничится кол-вом потоков равным кол-ву ядер, если-же есть обращение, например, к удаленной базе данных с длительными ожиданиями - то здесь нужно увеличить кол-во потоков в пуле больше чем 2*кол-во ядер можно попробовать сделать динамический пул - если запущеный поток последний в пуле, то создается еще один - т.е. пул никогда не бывает пустым, если-же поток не запускался определенное время, то он уничтожается - по идее для LIFO эта тактика должна быть довольно эффективна... ЗЫЖ да, и посмотрите все-таки boost::asio - возможно это как раз то, что вам нужно |
|||
|
||||
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
Ребята, всем огромное спасибо, буду смотреть и разбираться. Олег2005 и тебе спасибо за файл.
![]() -------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
Олег2005, это вырезка, а откуда? Если не секрет.....
-------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Это из моего учебника по сетевому программированию
![]() |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
-------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
vikaz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
MAKCim спс, за ссылку. Олег2005 и много у тебя там такого интересного? Можно ли как-то её почитать?
-------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
|||
|
||||
vikaz |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 869 Регистрация: 15.2.2006 Репутация: нет Всего: 12 |
Олег2005, спасибо еще раз за инфу. Но у меня по ней возникли вопросы. А именно к серверной части, так как в клиентской все просто.
Вопросы: 1. В фунции main в конце есть сл. код:
Сам вопрос, зачем в конце сл. строки?
Что ты пытаешься тут отправить. Как мне показалось, ты просто ошибся и я убрал эти строки. Но Код так и не заработал. Точнее часть. Сервер показывает, что клиент подключился, но сообщения не принимает и не отправляет! :( еще возник вопрос, в структуре мы не вводили данный параметр, но он присутствует: op->hEvent = 0; Это сообщение отредактировал(а) vikaz - 19.12.2008, 09:18 -------------------- ![]() Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ |
||||
|
|||||
Олег2005 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Посмотрите вот здесь
Там есть кое-какие комментарии.
Да нет, там не отправка - а прием от клиента - WSARecv Это поле из структуры OVERLAPPED, которая включена в структуру ovpConnection, и его имя - hEvent - по умолчанию. И еще - в функцию void SendToAll(char *buffer,unsigned long bytes) тоже надо добавить op->hEvent = 0; Это сообщение отредактировал(а) Олег2005 - 22.12.2008, 23:26 |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |