Russian Qt Forum

Qt => Работа с сетью => Тема начата: merke от Март 19, 2010, 14:26



Название: Коллективное написание многопоточного сервера на Qt
Отправлено: merke от Март 19, 2010, 14:26
Здравствуйте, дорогие форумчане!
Среди нас есть как начинающие программисты так и гуру. Но все кто либо писавший на любом языке программирования рано или поздно встречается с работой с сетью. В большинстве случаев требуется написать клиент/серверные приложения. В интернете существует большинство исходных кодов для других сред программирования в которых реализуются многопоточные сервера. Я уже много раз сталкивался  с задачей написания подобных приложений на Qt, но в меру моей не профессиональности программирования в данной среде, у меня не получалось реализовать рабочий многопоточный сервер. Рыл учебники, русскоязычные форумы, зарубежные, но ни где не мог найти простую, доступную реализацию сервера.
Я хочу предложить вам  написать общими усилиями многопоточный сервер на Qt. Проделанная нами общая работа, очень поможет в будущем программистам, которые будут сталкиваться с подобной задачей. Они смогут получить готовые классы, которые будут интегрировать в свои проекты.
Предлагаю всем кто заинтересован в данном проекте, составить техническое задание, собрать всю необходимую информацию, обсудить все возможные варианты реализации.
Предполагаю, что у кого то уже есть подобная реализация, пожалуйста поделитесь исходными кодами. Мы Вам будем очень благодарны!!!

С уважением, Александр!


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: ieroglif от Март 19, 2010, 20:39
перепиши GNE - все тебе будут мега благодарны =)


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: SABROG от Март 20, 2010, 00:17
Предлагаю всем кто заинтересован в данном проекте, составить техническое задание, собрать всю необходимую информацию, обсудить все возможные варианты реализации.

Тогда нужно сразу договориться. Никаких boost::asio и сторонних сетевых библиотек. Реализация полностью на Qt.
Добиться решения 10k (http://www.kegel.com/c10k.html) проблемы на Qt не выйдет из-за того, что в отличае от asio и других библиотек Qt не использует Completion Port в Windows. Кто может сравнить реализацию под linux, использует ли Qt оптимальную работу с сокетами в этой ОС или тоже иная реализация?

Думаю будет правильным включить QAbstractSocket::LowDelayOption, чтобы отрубить Nagle алгоритм.

Без потоковый вариант (асинхронный, но single threaded) думаю можно не рассматривать. Нам нужна закадровая работа сервера, которая не будет прерывать основной поток и блокировать главный цикл событий. Значит нужно на основании каких-то эмпирически вычесленных параметров выбрать максимальное количество потоков в приложении, между которыми будет распределяться вся работа с сокетами. Вариант "один поток - один клиент" - утопия, его не рассматриваем.

Техническое задание:
- реализовать ограничение по скорости как на прием, так и на отправку (можно сделать через ограничение размера буффера сокета)
- реализация подобия firewall'a, чтобы добавить возможность отвергать соединение с IP адресами и/или MAC адресами. Пример можно взять в IRC, где можно банить конкретный IP, целиком подсеть или шлюз.

Если будем писать протокол, то:
- использование QDataStream для приема/передачи команд
- реализация сжатия для передаваемых пакетов
- реализация ping-pong команд для определения задержек (latency) и жив ли наш клиент/сервер на той стороне. Не является ли соединение - зомби.
- реализация шифрования пакетов
- квотирование по скорости, времени, переданных и/или присланных объемов данных (в случае использования сервера в качестве файлообменника)
- система авторизации (в этом случае без БД не обойтись)
- использование QtConcurrent для распараллеливания долгих операций (собственные, более быстрые, варианты алгоритмов сжатия и шифрования)
- для передачи файлов реализация p2p алгоритма, хеширование, докачка. Чтобы пользователи могли выкачивать файлы даже тогда, когда сервер не доступен, по аналогии с torrent, directconnect.
- реализация системы обновлений клиента (патчи/апдейты и тому подобное) (прим: у протокола должна быть версия, чтобы старые клиенты не могли общаться с сервером)
- изучение возможности присвоить клиентам уникальные ID, чтобы можно было их идентифицировать не только по IP или логину, но и компьютеру на котором работает клиент. Привязка к компьютеру, пусть даже с защитой от дурака и без использования ОС зависимого API, но чтобы было не очевидно.
- реализация CAPTCHA для отсеивания ботов
- реализация "ловушки" в ответ на неверную команду от клиента (telnet, бот и т.п.) Сервер передает сообщение клиенту "не подключаться в течении n времени". Если в течении этого времени клиент подключается, то он банится на определенный промежуток времени. Позволит отсекать "блуждающих" по портам ботов, которые могут пытаться определить протокол и реализовать попытку взлома.
- использование UDP протокола для "необязательных" операций. Поиск файлов, попытка быстрого подключения для проверки чего-либо.
---
Пока всё. Нужно найти способ сделать стресстест для такого сервера. Прикинуться smtp серваком например и разместить на форумах фиктивный e-mail адрес с доменным именем :) Через некоторое время стабильно начнет сыпаться спам раз в секунду или быстрее. Можно заделаться под DC клиент и отвечать на все поисковые запросы, особенно TTH, лавина соединений хлынет очень быстро. Думаю уговаривать людей потестировать сервачок ни к чему не приведет.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: hackoff от Март 20, 2010, 06:14
Вариант "один поток - один клиент" - утопия, его не рассматриваем.
Расскажите пожалуйста, чем плох этот вариант?


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: merke от Март 20, 2010, 07:54
SABROG, огромное спасибо что откликнулись, вы прекрасно поставили задачу!
Теперь давайте порассуждаем.
Отключение алгоритма Нагла может существенно уменьшить скорость. Суть алгоритма (вообще то RTFM) для непосвящённых - если Ваше приложение отправляет данные по 1 байту и делает это часто, алгоритм Нагла постарается собирать данные в более крупные сегменты. Отключение его приведет к тому, что стек будет пытаться отослать данные немедленно, что приведет к весьма нерациональному использованию канала - на 1 байт данных будет приходиться около 40 байт служебных заголовков.

Пожалуйста, SABROG, объясните почему не следует применять метод "один поток - один клиент"?

Насчёт протокола:
Цитировать
использование QDataStream для приема/передачи команд
Как я помню при передаче данных с использованием QDataStream в поток в начало дописывается 4 байта служебной информации. Поэтому клиент например написанный на Visual Basic или в другой среде уже не сможет корректно общаться с сервером. Это конечно же извращение писать клиента на vb, но всё же, не так давно я занимался такой порнографией, только сервер был на vb, а клиенты на кутях.

Вы описали столько дополнительных возможностей, которые можно прикрутить к проекту, это здорово. Но сейчас чтобы не заморачиваться всем тем, надо для начала реализовать саму голую, продуманную, стабильную многопоточность. Сервер будет писаться из расчётов, что количество одновременно соединённых клиентов будет >1000. Тут в помощь придёт большой опыт наших специалистов на форуме, я очень надеюсь, что они нам помогут найти рациональное решение реализации столь загруженного сервера, который будет в меру своей объёмности по вычислительным процессам, не таким ресурсоёмким.

Пожалуйста, дорогие форумчане, присоединяйтесь к проекту! Перспектива колоссальная! Если мы реализуем такой проект, который описал нам SABROG, это будет огромнейший вклад!

И так, на повестке дня, все у кого есть идеи, может готовые решения реализации многопоточного сервера различными методами, выкладывайте, объясняйте почему именно так вы предлагаете реализовать многопоточность!

Огромное спасибо всем кто уже присоединился к проекту!



Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Март 20, 2010, 12:07
Всем привет!
Код:
"один поток - один клиент"
- отбрасывайте сразу, моя Вам совет!!!! Писал(да и щас дописываю его) такое приложение, изначальный вариант был 1 клиент - 1 поток, потом столкнулся с проблемой что потоки жрут слишком много виртуальной памяти! Попробуй запусти 1000 потоков и пусть у всех в run стоит msleep(1000) (эмитация соединения) - посмотрите сколько памяти сожрется!!!!!!

    Реализовал приложение на асинхронных сокетах, но есть свои небольшие непонятки....а так идея хорошо насчет совместной разработки...только кто будет координатором и под какую сеть(задачу) будет сервак????


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: SABROG от Март 20, 2010, 13:42
Отключение алгоритма Нагла может существенно уменьшить скорость. Суть алгоритма (вообще то RTFM) для непосвящённых - если Ваше приложение отправляет данные по 1 байту и делает это часто, алгоритм Нагла постарается собирать данные в более крупные сегменты. Отключение его приведет к тому, что стек будет пытаться отослать данные немедленно, что приведет к весьма нерациональному использованию канала - на 1 байт данных будет приходиться около 40 байт служебных заголовков.
Если рассматривать общение по протоколу Ethernet как серию мелких пакетов (меньше или равное MTU - 1500 байт - 40 байт заголовка), то у сервера есть аж 1460 байт для отсылки команды. Если в таком пакете вместе с опкодом команды передаются данные, которые умещаются в 1460 байт, то между каждой командой будут задержки. Первая может возникнуть, если общий объем данных не дотягивает до полноразмерного пакета. 1459 байт, вместо 1460. Алгоритм Нагла будет ждать еще данных от сервера. Тут мне не понятна такая вещь, если пакет от сервера самый первый, то фраза в большинстве статей "будет ждать ответа ACK от клиента (200 ms delay) перед посылкой следующего пакета" приводит в замешательство. Если предыдущего пакета небыло, то что, deadlock? Понятно, что если длину данных невозможно разбить без остатка на MSS - 1460 байт, то каждый раз мы будем иметь задержку из-за Нагла на последних пакетах.

В общем как ни крути, а применение этого алгоритма целесообразно только в случае экономии траффика, так как при отключенном Нагле для отправки одного байта TCP пакет наполняется "воздухом" до максимального размера MSS. В локальных сетях в нем совершенно нет никакого смысла.

Вообще хотелось бы слышать лично ваше мнение, вместо копирования чужого с форума : http://forum.sources.ru/index.php?showtopic=184504 Тем более, что чуть ниже человеку дают недвусмысленно понять, что он не прав. Отключение алгоритма Нагла в большинстве случаев не приводит к снижению скорости передачи, а наоборот.

Пожалуйста, SABROG, объясните почему не следует применять метод "один поток - один клиент"?
У тебя оперативной памяти не хватит на 1000 клиентов + создание и уничтожение потоков дополнительная нагрузка на сервер.

Насчёт протокола:
Цитировать
использование QDataStream для приема/передачи команд
Как я помню при передаче данных с использованием QDataStream в поток в начало дописывается 4 байта служебной информации. Поэтому клиент например написанный на Visual Basic или в другой среде уже не сможет корректно общаться с сервером. Это конечно же извращение писать клиента на vb, но всё же, не так давно я занимался такой порнографией, только сервер был на vb, а клиенты на кутях.
Хмм, о клиентах не на Qt я не подумал. Но если отказаться от QDataStream, то мы потеряем переносимось между платформами, он все-таки Byte-Order независим. Может быть проще будет вытащить эти "магические" значения из исходников Qt?

---
Общение между потоками сервера можно реализовать через систему сигналов и слотов. Несмотря на кажущуюся потерю в скорости у этой системы есть несомненные плюсы. При использование мутексов, callback'ов или паттерна типа Observer вызывающий всегда блокируется до завершения вызываюемой функции. В случае двух потоков это приведет к остановке одного, пока другой будет что-то обрабатывать. По сути это ничем не будет отличаться от однопоточной системы. Нам это не нужно. Благодаря системе событий Qt мы можем отправить сигнал и не дожидаясь ответа продолжить обрабатывать других клиентов. Ответ, как результат работы слота, будет приходить тоже как сигнал. Например клиент запрашивает файл. В данный момент мы находимся в одном из 5 потоков, каждый поток обрабатывает 1000/5 = 200 клиентов. Представим, что наш сервер это Макдональдс. Клиенты стоят в 5 очередях, которые обслуживает 5 кассиров. Каждый кассир принимает заказ и передает его на выполнение другим сотрудникам, повору например. При этом мы видим, что кассир не дождавшись выполнения заказа уже берет заказ у следующего клиента. У нас будет также, 5 потоков обрабатывают команды клиентов и передают на выполнение одному или двум потокам, которые выполняют некую долгую блокирующую операцию. Так вот клиент запрашивает файл. Сначала мы спрашиваем у остальных клиентов, есть ли у них уже этот файл и если есть, то просим их подключиться к запрашиваемому клиенту для передачи кусков, иначе сами передаем ему список таких клиентов, если он за фаерволом. Если у них такого файла нет, то передаем имя файла в другой поток, который читает его с устройства, кеширует некий объем данных, чтобы минимизировать количество обращений к диску, так как эта операция всегда долгая. И по готовности передает сигнал. Получив этот сигнал мы зависываем порцию данных. Сигнал может содержать информацию о том сколько данных готово для пересылки, какому клиенту они предназначаются. Стоит ли ожидать еще данных. С целью разгрузки сервера можно заставить все подключенные клиенты скачать каждому свой диапозон данных файла, который запрашивал другой клиент. После пересылки дать им команду подключиться к запрашиваемому и отдать свой кусок. При этом если в будущем кто-то запросит тот же файл, то большинство клиентов уже будут иметь какую-то его часть и серверу даже не будет необходимости его передавать заново. Система хорошо будет работать на новинках. Значит должен быть счетчик популярности для каждого файла, чтобы можно было принять однозначное решение о распределении кусков файлов по клиентам. С целью минимизации траффика между клиентом и сервером было бы рационально заставить два и более клиентов общаться между друг другом напрямую минуя сервер. Значит нужно каждому подключившемуся клиенту сообщать о клиентах, которые уже подключены к серверу, а им в свою очередь сообщить о новом подключившемся или отключившемся. В идеале хотелось бы организовать децентрализованную систему, где любой из участников сети мог бы взять на себя роль сервера, таким образом, чтобы при отказе в работе основного сервера другой смог бы занять его место. Также хотелось бы создать интеллектуальную систему, которая смогла бы вычислять самый быстрый маршрут между клиентом и сервером. Таким образом, чтобы другие клиенты могли выступать в роли proxy серверов. Зачастую в том же DirectConnect другие компьютеры из пиринга не доступны для скачивания файлов, однако часто есть промежуточные клиенты, которые видят сразу обе подсети и могут наладить связь между клиентами из разных сетей. Но это уже идеи касающиеся конкретно p2p технологий.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: merke от Март 20, 2010, 13:56
garryHotDog, Добро пожаловать! :)
Спасибо за все разъяснения по поводу почему лучше не использовать метод "один поток - один клиент"!

Да, изменить исходники класса QDataStream не составит труда. Насчёт переносимости я совершенно согласен.

Я хотел бы быть координатором, но не настолько хорошо знаю Qt. Нужен программист, который уже занимался командным написанием проектов через интернет. Потому что здесь нужно будет чётко распределять задачи между программистами и согласовывать работу. Предлагаю на роль КООРДИНАТОРА - SABROG. Вы согласны?

Давайте все вместе определимся под какую задачу будет писаться сервер! Может напишем сетевую игру, например Монополия?! Или есть какие либо другие интересные предложения?




Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: SABROG от Март 20, 2010, 14:59
Давайте все вместе определимся под какую задачу будет писаться сервер!

Меня интересует идея написания клиента и сервера в одном лице. Хотелось бы построить децентрализованную анонимную файлообменную сеть, с зашифрованным протоколом. Распределить ответственность за распространение файлов равномерно по каждому участнику такой сети. Клиенты будут выкачивать "не нужные" им куски популярных файлов (в пределах настроек естественно, не больше, но и не меньше определенного объема), чтобы потом были тысячи альтернативных источников. Пользователь такой программы никогда не будет на 100% уверенным какие части и каких файлов он передал другим. Я знаю, что таких проектов несколько, но ни один из них не удовлетворяет полностью.
В торренте хорошо то, что ты можешь обсудить раздачу, посмотреть постеры, скриншоты, дополнительное описание, отзывы. Поэтому правильно было бы написать протокол, который позволит делать все тоже самое, но в децентрализованной сети, где трекера не будет как такового. В этом мог бы помочь движок WebKit'a. Предположим, что у меня есть фильм, я оформил раздачу. Дижок клиента создан так, что ты не можешь знать какой именно клиент хранит этот фильм. Ответ может приходить как от временного сервера, так и через "псевдо" прокси клиентов. То есть все клиенты видят общий список фильмов, но владельцев не видят, так как информация о них просто не приходит, а не скрывается. Если я хочу скачать раздачу, то вместе с фильмом я скачиваю дополнительную, служебную информацию, о раздаче. Таким образом, если оригинальный владелец пропадет из сети, то любой клиент, который качал этот фильм имеет на своем компьютере оформленную раздачу с постерами, описанием, скриншотами и обсуждением. Таким образом, на каждом клиенте хранится не вся база "форума", а лишь та часть, которая ему была интересна. При добавлении нового комментария к фильму информация об обсуждении обновляется у всех скачавших этот фильм. Если человек ничего не качал, а только принимает участие в обсуждении, то информация обновляется лишь у тех у кого есть этот фильм. Если в данный момент нет ни одного клиента с раздачей, то её нет и в списке "топиков", обсуждение невозможно до тех пор пока не появится хотябы один источник. Если после добавления комментария к фильму заходит еще один источник, то ему пересылаются все новые изменения, которые произошли в момент его отсутствия с раздачами, которые он имеет на своем компьютере. Синхронизация короче.

В данном случае речь идет о пиратском контенте. В связи с "оживлением" правительства в отношении пресечения пиратов эта тема сейчас наиболее остро стоит. Я сторонник такой идеологии "Послушал музыку - не понравилась, покупать не обязан. Посмотрел фильм - не понравился, покупать не обязан. Поиграл в игру - не понравилась, покупать не обязан". Сколько люди затратили денег на создание фильма это только их проблемы. Людям, которым фильм не понравился должны возвращать деньги в кинотеатрах. Если ты создаешь продукт, то все риски возлагаются только на тебя. Если я потрачу огромную сумму, чтобы нанять вертолет, дорогих актеров, особнях на мальдивах, а потом сниму треш, то деньги, которые я "отобью" у кинотеатров по сути будут ворованными. Хотябы взять тот же сайт IMDB, много ли фильмов оценок ниже 3 из 10? Докучи! Это значит, что примерно 2/3 людей вышли из кинотеатра или остались недовольными покупкой DVD от просмотра фильма, а значит отдали свои деньги ДАРОМ ни за что.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Март 20, 2010, 19:19
Я как понимаю ты предлагаешь написать не только клент\сервер, но и новый протокол вообще?! Идея мощьная просто она может оказаться не востребованной....не просто так ЕСТЬ и ИСПОЛЬЗУЮТСЯ P2P(различные вариации протокола), торрент и т.д....изобретать новый велосипед??? есть ли смысл???

Я как понимаю тема топика была - разработка приложения на QT !? Предлагаю, написать клент\сервер под уже готовую сеть например Gnutella 2.0 или Gnutella 0.6....это уменьшит время разработки самого протокола....это лично мое мнение....ла и еще - а зачем шифрование для файло обменной сети???? это только замедлит работу клиента\сервера!


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: SABROG от Март 21, 2010, 01:10
Да смысла нет конечно писать с нуля. Был вроде клиент Qtella, да в 2004 году удачно сдох. А сейчас в gnutella у всех одна Shareaza стоит, а она на MFC написана. Грустно.

Может бота напишем какого (не обязательно для p2p)? ;)


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Март 21, 2010, 01:41
вот Бот уже интересней...только нужен "умный" бот)))) нужна только сеть.....ща по гуглю что нибудь


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: IMPOMEZIA от Март 21, 2010, 10:04
Цитата: SABROG
Кто может сравнить реализацию под linux, использует ли Qt оптимальную работу с сокетами в этой ОС или тоже иная реализация?
Используется не эффективный poll вместо epoll.


Название: Re: Коллективное написание многопоточного 
Отправлено: mcrads от Март 21, 2010, 11:06
немного технической информации из практики (с чем сталкивался)... пардон если повторяю чьи-то идеи...
необходимо четко представлять себе механизмы работы задуманного. Так, например, я писал виртуальный файловый сервер и клиент к нему. Казалось бы что может быть проще? распараллелить подключения на потоки, все красиво и аккуратно. В результате я взял 10 подключений на поток. гиг оперативы выдержал около 150 клиентов. Но при этом файловая система могла выполнять единовременно только одну операцию. стал распараллеливать и ее. в результате производительная упала еще сильнее. Пришел к выводу что наиболее оптимальным решением будет литая ФС, асинхронная работа клиентов и лимит на длину пакета - чтобы успевались обслужиться и другие клиенты. Собстренно грубо это выглядит так: один клиент отправляет на 300 байт, другой 150. мы обслужили 100 байт первого, потом сто второго, еще сто первого, оставшиеся второго и оставшиеся первого. все в порядке очередности - кто постучался. Такой механизм не тратит лишние ресурсы на потоки и зависит только от производительности системы.

Однако если вы ИЗНАЧАЛЬНО задумали параллельную обработку - сервер можно смело делать многопоточным.
Учтите, что многопоточная обработка общих данных не всегда гарантирует 100% результат. (что такое мутексы я знаю, к тому же их использование сведет на нет распараллеливание обработки общих данных)

Хотя возможно я немного неправильно решал задачу - буду благодарен за поправки и замечания.

Систему команд я реализовывал путем записи в QByteArray определенной последовательности байт для каждой комманды. например первые 10 байт - команды, 3-5 байт - разделитель, остальное - данные, аргументы и тд.

Поправьте если что..


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Март 21, 2010, 19:46
для SABROG:

 Если не сложно разъясни мне пожалуйста следующее:

 Как я понял алогритм Нагла это в своем роде буферизация на сокете, делается для того что бы не нагружать канал маленькими пакета, типа данные 1 байта (а служебка будет 20байт заголовок IP +tcp заголовок+ 14 байт заголовок Ethernet), так????

  Если да, то что нам дает функция сокета flush() - по ее описанию - отправляем имеющиеся данные на сокете,в обход алгоритма Нагла что ли????

 и как отключить алгоритм нагла в QT сокетах???


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: bvn13 от Май 11, 2010, 22:15
мне тоже интересно принять участие. Но, боюсь, что я буду самым малознающим в отношении реализации клиент-серверных приложений :)
Но я тоже хочу поиметь от этого проекта не только опыт :)

Насчет идеи. Давайте, как и предложил топикстартер, не зацикливаться на конкретной реализации протокола. Давайте вместо передачи файлов или еще чего будем передавать рандомные фразы? ну типа примера от разработчиков кута. Таким образом будет готовый рабочий шаблон многопоточного сервера/клиента (здесь можно прикрутить различные обработки передаваемых данных: шифрование, упаковка, еще что-нибудь). А уже на него "нанизать" конкретную реализацию протокола.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Май 11, 2010, 22:21
 судя по всему тема не пройдет......идея сдохла ;D


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: niXman от Май 11, 2010, 23:02
почему сдохла?
что - кого не устроило?


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: ieroglif от Май 12, 2010, 00:21
ээх.. если б не нужда зарабатывать деньги - принял бы участие с большим удовольствием. =((


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: garryHotDog от Май 12, 2010, 09:46
так и не решили кто будет координатором!!!и активности ни какой


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: ecspertiza от Май 12, 2010, 15:04
Может реализовать, API на Qt много поточного сервера, затем на этом API реализовать демку клиент-серверное приложение, типа танчиков(денди), только могут подключаться куча народу(1000 человек) и устраивать батл :) По моему было бы забавно.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: Atan от Июнь 30, 2010, 01:49
Привет всем, кто писал и следил над этой темой.
Я думаю, что её обсуждение напрасно остановлено и предлагаю всем желающим снова присоединиться.

Меня недавно тоже посетила идея написания сервера и клиента для сетевого общения на основе собственного протокола с шифрованием, естественно, на Qt. В зависимости от глубины проработки, формат общения будет укладываться от многоканального чата а-ля icq, или вырастет до полноценного форума.

Принципы системы:

Общение между клиентом и сервером происходит посредством коротких сообщений. Клиент отправляет комманду -> Сервер проверяет права клиента на её обработку -> Высылает клиенту ответ. Почти как в терминале *nix. Комманды к примеру такие: login, who, showprofile, showmsg, getfile. Для некоторых комманд предусматриваются аргументы, для других - ожидание дополнительного ввода от клиента.

Шифрование траффика. Судя по всему, эта тема хоть и поднята выше, но является достатночно тёмной для участников дискуссии (для меня тоже). Я сначала хотел для этой цели использовать QSslSocket, но быстро разочаровался в этом казалось бы беспроигрышном подходе, так как для этого нужно что-то скачивать, пересобирать Qt... (А что делать клиентам, которым тоже необходимо Ssl на компе как-то иметь!?) Благодаря вышеизложенным причинам крипт придётся делать свой. И я его (алгоритм) таки почти написал. Но пока не проработал механизм аутентификации, передачи сертификатов/ключей, имею высказать следующую мысль: в ходе сеанса связи клиент и сервер обмениваются зашифрованными посланиями, в которых содержится само сообщение + ключ, которым должно быть зашифровано следующее послание от "собеседника". Насколько могу судить, единственная возможность расшифровки для третьей стороны - это просечь момент, когда "собеседники" только-только обменялись ключами, в начале сеанса. Иначе - успеть забрутфорсить и разгадать ключ, пока он не поменялся снова. Вероятность этого - 0,00001%. Схема настолько проста, что мне прям не верится, неужели всё так гладко?

Многопоточность. Это в общем-то та вещь, с которой у меня не получается разобраться своими силами. Ещё больше раздосадовало то, что доступ к БД с помощью QSqlQuery возможен только из потока, в котором соединение с базкой и было установленно. Цитирую из QtHelp: "A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported."

От идеи p2p я отказался по причине дополнительной сложности её тестирования и реализации. Это мне пока не по силам. Но, с другой стороны, p2p можно включить и позднее, благо будущий протокол этого не запрещает. Её сущность возможно будет заключаться в том, что зарегистрированный пользователь при желании будет брать на себя часть информации, которую хранит сервер, и при случае отправлять её нуждающимся в ней клиентам по команде сервера.

Дабы как-то разжечь дискуссию и не быть голословным, прикрепляю к сообщению архив с исходниками сервера и простейшего клиента командной строки. Сервер уже умеет коннектиться к БД, загружать оттуда настройки, производить идентификацию клиента по логину-паролю и проверку прав доступа. Реализован простенький чат. Как было сказано выше, работает в однопоточном режиме. Параметры коннекта к БД (адрес, тип, логин-пароль) прописываются в файлике bd.ini. С согласия знакомого владельца сервака с MySQL я могу дать параметры коннекта к его базе.

P.S. я конечно осознаю, что разработка данной системы на Qt, как и сама система, не слишком рентабельное дело в смысле его "велосипедности". Не покидает вопрос о том, зачем это писать, если есть web-сервера со своей многопоточностью, PHP со своей универсальностью, если есть Jabber, в конце концов... У меня рационального ответа не нашлось (просто привлекательна сама мысль о написании клиент-сервера на Qt). Поэтому, пока не надоело самому, прошу поддержать и посодействовать всех единомышленников-добровольцев.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: niXman от Июль 05, 2010, 06:25
не нужно писать сервер под конкретную задачу - это тупо и одноразово.
если и писать, то модель, в которой каркас - это обработчик запросов/ответов, и статическую или динамическую регистрацию "прокси серверов типов запросов/ответов" и их соответствующих обработчиков.
сам в голове кручу эту идею уже некоторое время. некоторые части из всей идеи уже реализовал в других проектах. самое сложное - разработать правильную структуру проекта.

но я хз как на Qt можно что-то подобное написать...ИМХО.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: ieroglif от Июль 05, 2010, 12:37
Лично мне необходим клиент-серверный каркас, на основе которого можно было бы делать игровые проекты.
Разумеется, под Qt :)
На данный момент есть в сети проект кроссплатформенного GNE (Game Network Engine) - думаю что было бы очень приятно переписать его под Qt :) Либо - это хороший толчок :)


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: JamS007 от Июль 27, 2010, 20:00
Я бы с удовольствием присоеднился, но, чувствую, толку с меня мало будет... Наоборот, хотелось бы чему-то научиться, поработать в команде, набраться опыту.


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: Igors от Июль 27, 2010, 20:19
Много раз использовал multi-threading для относительно небольших задач и мнил что понимаю этот аспект/вопрос  :) Однако первый же серьезный запрос заказчика сделать существующее application multi-threaded показал что на деле я понимаю очень немного  :) Напр прямолинейное использование mutex'ов будет в минус (а не в плюс). Масса проблем возникает на уровне что и как распараллелить и.т.п

Присоединиться я не смогу, но дело хорошее, welcome


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: merke от Июль 28, 2010, 08:04
Вот выкладываю пример клиент-серверного приложения (сервер многопоточный). Исходник найден на одном форуме. Думаю, данный исходник даст толчок к началу обсуждений.

http://turbobit.net/awvsvkcznij0.html (http://turbobit.net/awvsvkcznij0.html)


Название: Re: Коллективное написание многопоточного сервера на Qt
Отправлено: labview от Июль 31, 2010, 15:31
Привет!

Я удачно сделал такой проект под названием Чат на другом языке программирования. Сервер был устроен так:

Два параллельных потока. Один поток рассыльщик, второй постоянно ждёт открытия соединения. Как только клиент пытается открыть соединение, сервер открывает отдельный поток. То есть каждый клиент имеет свой поток.
Клиентский поток считывает данные через TCP/IP и отсылает эти данные через очередь рассыльщику, который отправляет сообщение всем имеющимся клиентским потокам, которые в свою очередь отправляют сообщение через TCP/IP всем клиентам.

Система работает, серверная программа заинсталлирована на веб-сервере, протокол открыт. Если есть интерес я могу попробовать переписать всё на Qt. Если кто то хочет попробовать написать клиента для рабочего сервера, могу описать используемый протокол (он очень простой). Если кому то нужны подробные пояснения к организации сервера или клиента, могу описать.

Прилагаю ссылку на скрин клиента и исходники кода на языке LabVIEW:
http://labviewportal.eu/ru/internet-tehnologii/154-2009-07-25-16-53-48

Ссылка на бурное обсуждение этого проекта (там есть много пояснений):
http://labviewportal.eu/viewtopic.php?f=142&t=853

С уважением!