![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Нужно сделать web-интерфейс для программы. Т.е. чтобы заходя браузером на определенный порт компьютера, где запущена эта программа можно было увидеть сайт, через который можно управлять данной программой. Также нужно обеспечить кроссплатформенность программы (windows, linux). Написание программы на php + веб сервер не подходит. Т.к. необходимо иметь программу и веб сервер в одном комплекте.
Вопросы: 1. Если писать программу на Borland C++, как начать? Вроде нужно создать новый проект: File - New - Other - web Server Application. Тут сразу встает вопрос, какой тип выбрать далее. Т.к. я не собираюсь писать ни CGI скрипт, ни библиотеку к апаче, а самостоятельный exe-шник, то, похоже, надо выбрать последний пункт - Web App Debugger Executable... Подскажите что и как, плз? 2. По кроссплатформенности, по идее, можно написать windows приложение и для запуска под linux использовать WINE- эмулятор windows (не совсем эмулятор, как они пишут у себя на сайте). Тогда сразу встает вопрос, если я открываю порт на компьютере API функциями, то откроется ли порт под linux через этот WINE? 3. Если для кроссплатформенности писать не на Borland C++, а на чем-нибудь другом, то на чем? Сразу на ум приходит .NET, ведь оно для кроссплатформенности вроде как и сделано. Но я в нем новичек. Посоветуйте, стоит ли заниматься написанием данной программы например на C# .NET или все-таки на c++ не так уж и сложно реализовать? Приветствуются все советы и ссылки |
|||
|
||||
| jonie |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 15 Всего: 118 |
-------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
| Vasay |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2097 Регистрация: 8.3.2006 Репутация: нет Всего: 73 |
TheDestroyer,
Только вчера был пост на эту тему: http://forum.vingrad.ru/forum/topic-259024.html
Есть, конечно, mono для C#, но он сильно отстает от MS версии .NET, да и с лицензией там не так чисто. Если кросплатформенность нужна - то это либо Java (кстати, есть классы, реализующие функционал web-сервера), либо Qt (и ему подобные кросплатформенные библиотеки). п.с. а вы уверены, что вам нужен такой изврат как веб-сервер в вашей программе? Это сообщение отредактировал(а) Vasay - 13.5.2009, 19:30 -------------------- Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны. |
||||
|
|||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Python/Ruby почему не рассматриваются?!
Почему изврат? WebUI управления плеером или торрент-клиентом вещь очень типичная... |
||||
|
|||||
| Vasay |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2097 Регистрация: 8.3.2006 Репутация: нет Всего: 73 |
Python - думаю тоже возможно. Просто я с ним и его возможностями незнаком. Ruby - в те времена когда я им интересовался, для написания веб-сервера он был не пригоден, так как имел проблемы с многопоточностью.
Может, с "изварат" я погорячился, иногда такой подход может быть необходим, переформулирую вопрос - TheDestroyer а Вы точно уверены, что Вам это нужно (может использование веб-сервера будет удобней, или вообще запустить приложение в контексте сервера приложений)? Это сообщение отредактировал(а) Vasay - 13.5.2009, 20:33 -------------------- Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны. |
||||
|
|||||
| Vasay |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2097 Регистрация: 8.3.2006 Репутация: нет Всего: 73 |
Да, если речь идет об веб-интерфейсе к программе (т.е. веб-сервере внутри программы), то начинать надо не так:
А создать обычное десктоп приложение (с GUI или без - зависит от Вашей задачи), и внутри него, в отдельном потоке реализовать вебсервер - открыть сокет на прослушивание определенного порта и обрабатывать входящие запросы... Недавно на этом форуме мелькали примеры, как это реализуется на с++ и Java. Однако, я не стал бы использовать Builder для кросплатформенной задачи. Если есть желание писать именно на c++, то посмотрите в сторону qt Вот, кстати, примерчик: http://doc.crossplatform.ru/qt/4.5.0/netwo...tuneserver.html. Для работы из веб-браузера потребуется реализовать протокол HTTP (вот пример для QT http://doc.trolltech.com/solutions/3/qtser...ple-server.html ). Единственный минус QT - то что требуется перекомпиляция под разные системы. С Java проще - достаточно наличие jre в системе. Добавлено через 13 минут и 15 секунд В Java есть класс реализующий HTTP сервер, предназначенный как раз для реализации встроенных http серверов: http://java.sun.com/javase/6/docs/jre/api/...ge-summary.html Это сообщение отредактировал(а) Vasay - 13.5.2009, 20:55 -------------------- Придумать идеальную защиту от дурака невозможно, дураки, наудивление, изобретательны. |
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо за ответы.
Поясню цель приложения, веб интерфейс это его главная функция, оно должно предоставлять пользователю управление собой через браузер. Необходим самостоятельный сервер для того, чтобы не зависеть от установленного веб сервера у пользователя (его может и не быть) и его настроек. Также надо чтобы никто не копался в исходном коде и не модифицировал его. Значит надо в конечном итоге иметь скомпилированный фаил. jonie, это под VC++? Про Qt даже не слышал, интересное решение по кроссплатформенности. Получается по требованиям отвечают так: Самостоятельный веб сервер: BC++, .NET, Java, Qt, Python, Ruby(?) Кроссплатформенность: BC++((?)Через WINE), .NET((?) необходим Mono), Java, Qt, Python, Ruby В принципе, перекомпиляция под разные операционные системы не критична. Защита: BC++, .NET, Java, Qt, Python(?), Ruby(?). С Ruby дело не имел, на Python-е кое-что делал, но там все в исходных кодах, по которым при запуске среды создавались откомпилированные файлы и они уже выполнялись. Наверное для защиты можно распространять только откомпилированные файлы. У кого есть опыт или возможность проверить будет ли корректно работать созданный в BC++ 2009 веб сервер под Linux (из под WINE), сообщите, плз. Пока изучаю все по данной теме. Все советы, примеры и ссылки приветствуются. |
|||
|
||||
| isergey |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 28.5.2008 Репутация: нет Всего: нет |
Уважаемый. Для того чтобы управлять приложением через веб интерфейс, тебе нужно запустить в нем веб-сервер. Благо, это позволяет сделать множество библиотек. В принципе протокол HTTP не такой уж и сложный, так что ты можешь сделать его минимальную реализацию и сам. Крутиться твой сервер будет либо отдельным потоком, либо отдельным приложением. В первом случае, полученные данные через HTTP запрос будут изменять внутренне состояние переменных программы. Во втором случае, твой сервер общается с основной программой через какой-нибудь конфигурационный файл (программа или сервер периодически читают его и изменяют свое состояние).
Есть в питоне, в стандартной библиотеке, simpleCGIServer. Запускаешь скрипт и у тебя работающий CGI сервер. Укажешь ему где располагается директория с CGI скриптами, а в самих скриптах обрабатывай http запросы и пиши результаты в файл общения с основной программой. CGI скрипты можешь писать на чем хочешь, но лучше на питоне, для этого там тоже есть библиотека CGI. Удачные пример управление программой через веб интерфейс - это всем известный µTorrent http://www.utorrent.com/documentation/webui/ Конечно было бы не плохо, если бы ты в своей основной программе веб сервер сделал сам. Тогда получишь опыт работы с сетевыми сокетами и опыт работы с многопоточностью. Единственный минус в том, что такое решение может быт дырявым и не стабильным (неправильно обработал данные и все твое приложение падает). Но, как говориться, волков бояться - в лес не ходить ЗЫ. Только не надо использовать никакие с++ билдеры. |
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
WebUi сам активно использую, с многопоточностью опыт работы есть.
CGI скрипты, хорошо, но не подходят из-за открытости исходного кода как и php. Так у меня есть написанный на php вариант программы, но в php под windows не работает многопоточность (forking) и исходный код не скроешь (про Zend и т.п. знаю, но это не выход в данном случае). Склоняюсь к Qt, качаю и буду ставить. На сайте Qt они предлагают использовать их родную среду, также народ пишет, что очень удобно использовать Qt в MS VC++. Скажите пожалуйста, какую среду для разработки лучше использовать? |
|||
|
||||
| isergey |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 28.5.2008 Репутация: нет Всего: нет |
Я конечно не знаю, но по моему, если ты не используешь коммерческую версию QT, тебе нужно открывать исходные коды.
А по поводу скрытия исходного кода, никто не запрещает использовать питон скрипты компилированные в байт код т.е. *.pyc |
|||
|
||||
| sdukshis |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 92 Регистрация: 23.3.2009 Репутация: нет Всего: 1 |
Qt - хорошая библиотека для кроссплатформенной разработки, но рассчитана она, в первую очередь, на создание клиентских приложений.
Из все платформонезависимости Вам скорее всего понадобятся только сокеты, потоки и операции с файловой системой. Для сокетов можно использовать ASIO http://www.boost.org/doc/libs/1_39_0/doc/h...boost_asio.html Для потоков Boost Tread http://www.boost.org/doc/libs/1_39_0/doc/html/thread.html Для работы с файловой системой Boost Filesystem http://www.boost.org/doc/libs/1_39_0/libs/...m/doc/index.htm К тому же открытым остается вопрос демонизации, который по разному решается на различных платформах (насколько я знаю кроссплатформенной библиотеки нет). Хотя это можно сделать в ручную. Я думаю, что оптимальным вариантов здесь будет не использование библиотек boost или qt, а собственный платформонезависимый слой и условная компиляция. К сожаления с Java работал очень мало. Но если все эти вопросы там хорошо решены, то выбор явно в её пользу. |
|||
|
||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Qt с 4.5 под LGPL. Ни раз уже здесь обсуждалось
А вот это да. Более того - нормальных декомпиляторов питона (как ни странно) мне лично найти не удалось.. Т. е. по крайней мере новичков отпугнёт (что не скажешь о яве или дотНет). |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Абсолютно независимая реализация WEB сервера на голом С++ занимает около 1000 строк. Используются голые сокеты (исходник для Windows, но платформо зависимая часть winsock'а может легко быть портированна под linux и пр)
(Файлы StdAfx.* и utils.* - общие файлы всего проекта, не только WEB сервера. 90% содержимого для WEB сервера не нужно) Присоединённый файл ( Кол-во скачиваний: 40 )
websrv.zip 15,20 Kb |
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Результаты поисков (могут быть полезными всем, кто ищет информацию по данной теме):
Веб серверы с исходным кодом с поддержкой серверных скриптовых языков: http://code.google.com/p/mongoose/ http://www.lighttpd.net/ Простые веб серверы с отдельной директорией под html странички: http://www.pion.org/projects/pion-network-library http://www.pablosoftwaresolutions.com/html...web_server.html Библиотеки: http://www.webtoolkit.eu/ http://www.qtsoftware.com/ http://www.boost.org/doc/libs/1_39_0/doc/h...boost_asio.html Интересные примеры веб серверов, webio умеет создавать единый исполняемый фаил со встроенными страничками: http://www.codeproject.com/KB/IP/webio.aspx http://www.codeproject.com/KB/IP/webem.aspx http://www.adp-gmbh.ch/win/misc/webserver.html http://xaxxon.slackworks.com/ehs/ jonie и xvr, спасибо за примеры. Пример jonie откомпилировался, буду разбираться что к чему. Пример xvr не получается откомпилировать, почему-то не поинимает тип WSAEVENT в tcp_server.h. Видимо, что-то надо include-ить. Компилирую в В Visual C++, в нем я новичек, так что если несложно, подскажите что не так. Делаю так: чтобы создать проект выбираю в меню Фаил - Создать - Проект из существующего кода - добавляю все файлы в папке. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
WSAEVENT определен в winsock2.h, подключается через windows.h, который в свою очередь подключается через StdAfx.h -> utils.h
В любом случае от моих сорцов надо будет отрезать лишнее (оно там есть), и приделать свое (хотя бы доступ к файлам, которые вы хотите передавать через WEB сервер - оригинал их доставал из zip архива, помещенного в ресурсы exe'ника) |
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Продолжаю разбирать пример xvr:
На сколько я понял web_server.h и web_server.cpp - реализация поддержки http протокола, tcp_server.h и tcp_server.cpp - реализация сокетов и многопоточности. То, чего нехватает (лишнее) - убрал из StdAfx.cpp (класс InitSeqBuilder), остальное в utils пока не мешает, уберу позже. Проблему с нераспознанием типа решил установкой #include <winsock2.h> перед #include <windows.h> в utils.h Теперь много ошибок при компиляции типа:
т.е. не принимает функции setsockopt, listen,... Как это поправить? Еще несколько вопросов: 1. Что описывает класс HTTP_SendAns? Его функции вижу, а как это одним словом называется не пойму.. 2. Что означает последний параметр в функции send_file_data(d,find_file_type(get_file_ext(fname)),false); ? Похоже, что в хэдер будет добавлено Last-Modified: %s. Last-Modified — время последнего изменения пересылаемых данных. В каком случае это может пригодиться? 3. Мой сайт построен так, что он состоит не из отдельных html страничек, а из php файлов, которые выдают информацию на страницу в зависимости от запросов пользователя. Используется довольно много Javascript и Ajax. В данном случае вместо php используется C++. Вопрос: место куда лучше вставить динамическую генерацию кода страничек этоHTTP_SendAns::send_file1(string fname) ? Т.к. там string d=find_resource("web\\"+fname); в переменной d, как я понял хранится код странички, которую сервер отошлет пользователю. Получается здесь надо вставить мою функцию, которая будет динамически создавать сожержимое страницы. Но для генерации этого содержимого надо знать переменные POST и GET запросов, хорошо бы знать cookies для идентификации пользователя (как сессии в php) и хранения некоторых его переменных. В каком месте доступны эти переменные ( POST и GET запросов) и есть ли здесь реализация cookies? Это сообщение отредактировал(а) TheDestroyer - 21.5.2009, 00:29 |
|||
|
||||
| Andrey44 |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1501 Регистрация: 4.12.2006 Где: На работе Репутация: 2 Всего: 26 |
-------------------- ????? ??, ??????? ?????. |
||||
|
|||||
| xvr |
|
||||||||||||||||||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Угу
Занимается этим функция void send_asp(HTTP_SendAns &A, string s);, но она в эти исходники не входит. Поддержка JS довольно сильно переплетена с остальной частью программы, если надо, могу попробовать ее оторвать
Переменные и методы в нем:
|
||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо за ответы.
Удалось скомпилировать консольное приложение, поставив заглушки на недостающие функции, прилинковав Ws2_32.lib и создав главную функцию int _tmain(int argc, _TCHAR* argv[]) в web_server.cpp Пытаюсь запустить сервер, делаю так:
Как правильно инициализировать и запустить веб сервер? Функцию find_resource сделал такой, чтобы хоть что-то вывело клиенту:
Как JavaScript поддерживается на стороне сервера? |
||||
|
|||||
| xvr |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
web_server.do_init достаточно - он запускает run в нитке. (Макросы MAIN_FUNC и RUN_MAIN из StdAfx.h) После do_init нужно повиснуть (например в for(;;) Sleep(1000);}. Или крутить цикл оконных сообщений, или что нибудь еще
|
||||||||||
|
|||||||||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
А что может делать JavaScript на стороне сервера? Удалось получить тестовую строку на клиенте!
Похоже, это та часть, которую надо будет менять для компиляции этого исходника под linux? Разбираюсь с переменными, которые присылаются на сервер через GET и POST запросы. Поставил такой html код на выдачу клиенту:
Не удается получить значения переменных param1, param2. Как их правильно получить? A.req.get_cgi не возвращает эти параметры. a1,a2 или a3 передаются в A.req.cgi_lines[1], т.е. все параметры с формы будут всегда в A.req.cgi_lines ? |
||||
|
|||||
| xvr |
|
||||||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Формировать из .asp html
Угу, у моего сервера main выглядит так:
|
||||||||||||||||
|
|||||||||||||||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Да, помимо опечатки, еще идея неверная была. Теперь клиенту отправляется это:
Пытаюсь через A.req.get_cgi получить значения переданных параметров: В A.req.get_cgi(); надо передавать string id, а что это за id и как его получить? Если докопать до "корня" этой функции, то видно, что производится операция
Похоже, что создается список в виде "параметр, значение". Поясните, плз, что тут происходит и как правильно получить параметр 'answer' со значением 'a1', 'a2' или 'a3', в зависимости от того, что выбрал пользователь на странице. Или для получения параметров, переданных через GET запрос в адресе после знака "?" (handler.php?param1=123¶m2=321). Также если параметров несколько , то хотелось бы получить их все в переменные (как в php). Похоже, что надо узнать сколько их через A.req.cgi_lines.size и в цикле for присвоить соответствующим переменным их значения? Получается все переданные параметры со своими значениями будут храниться в A.req.cgi_lines независимо от того, как они были приняты через POST или GET? (возможно передавть POST и GET одновременно некорректно...) Это сообщение отредактировал(а) TheDestroyer - 24.5.2009, 19:39 |
||||
|
|||||
| xvr |
|
||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Их надо знать. Предполагается, что вы сами формировали формы, которые клиент отправил вам, так что параметры вам должны быть известны
|
||||||||||||
|
|||||||||||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо, с GET и POST ясно.
Разбираюсь с Cookies. Следуя Делаю так: для записи cookies пока для тестов в функции string HTTP_SendAns::send_file1(string fname) ставлю:
в функции void WEB_Server::process_file(HTTP_SendAns &A, string fname) Пишу:
Хочу прочитать записанное, на форме из предыдущего примера жму Submit или просто обновляю страницу. К сожалению, возвращается пустое значение. Смотрю в папке Cookies браузера (IE), созданных мной cookies там нет :(. Если заходить на данный веб сервер через FireFox, то в его cookies запись появляется. Но несмотря на это, считывание cookies при повторном заходе на страницу не происходит. Что тут может быть не так? Возможно, в IE проблема с синтаксисом самой записи, может необходимо указывать expires=... Как правильно получить cookies? Хорошо бы устанавливать время жизни cookies. Как получить текущее время + 30мин или +1 день с помощью функции print_time() ? Для записи cookies планирую сделать функцию в классе HTTP_SendAns: HTTP_SendAns::SetCookie(string item, string value). Также, получать параметры переданные через GET и POST, записывать и читать cookies надо в функции динамического формирования странички. Сейчас это функция string find_resource(string name) в файле StdAfx.cpp. Как лучше сделать доступными A.req.get_cgi("..."), A.req.get_hdr("Cookies") и SetCookie(...) в find_resource()? |
||||
|
|||||
| xvr |
|
||||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Cookie привязываются к URL (точнее имени сервера), откуда была полученна страница. Возможно IE хочет увидеть этот URL где то явно (в записях заголовка или атрибуте Path), точно не знаю
А функция для формирования ответа, это WEB_Server::process_file, туда и надо вставлять генерацию динамического контента Кроме того, есть специальная функция для обработки управляющих запросов - WEB_Server::process_cmd (она сейчас пустая) |
||||||||||||||
|
|||||||||||||||
| TheDestroyer |
|
||||||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Пытаюсь динамически сгенерировать страницу. Делаю это так:
Для проверки того, что получается при отправке и приеме сниффером (WireShark) проверяю запросы. Выявил странность: через браузер делаю запрос на сервер, сервер отвечает не одним пакетом, а двумя сначала
Проверил аналогичный запрос на сервер Apache, он отвечает одним пакетом
Возможно проблема с cookies из-за этого. UPDATE: Нет, похоже это не проблема, да отсылка идет по частям, но это не влияет на процесс. Удалось передать cookies следующим образом:
А принять так:
В итоге в str2 строка со значениями через точку с запятой. Похоже остется разделить их в переменные или массив для дальнейшей работы с ними. Для получения времени пришлось переместить функцию print_time в классе Http_SendAns из private в public Это сообщение отредактировал(а) TheDestroyer - 26.5.2009, 13:34 |
||||||||||||
|
|||||||||||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
|
|||
|
||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Сделал установку и получение cookies. В итоге появились функции
может пригодятся. Получать cookies точно также как и get_cgi или get_hdr. В процессе добавления поддержки cookies выявил некорректную работу функции trim в StdAfx.cpp, пришлось заменить
Вроде теперь есть все инструменты для создания сайта. Но теперь встал вопрос о том, как добавить большие фрагменты JavaScript кода в фаил веб сервера. Просто вбивать их строковыми переменными явно неправильно. Хотелось бы просто загружать в строковую переменную содержимое .js файла и использовать ее. Как сделать так, чтобы JavaScript код был в отдельном .js файле для его удобного редактирования до комптляции и чтобы после компиляции все упаковывалось в один фаил? Такойже вопрос и с картинками для сайта. |
||||
|
|||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Спасибо, пригодится
Чуть не забыл - для работы этой функции нужно прилинковать zlib Это сообщение отредактировал(а) xvr - 26.5.2009, 22:54 Присоединённый файл ( Кол-во скачиваний: 4 )
zipfile.zip 3,78 Kb |
||||
|
|||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Хотелось бы библиотеку zlib встроить в исполняемый фаил.
Скачал zlib1.2.3 c http://www.zlib.net/ (zlib source code, version 1.2.3, zipfile format) Нашел инструкцию как скомпилировать zlib1.dll, а как встроить в exe-шник пока не могу найти. Если несложно, укажите, пожалуйста, как это сделать, ссылки на информацию или просто ключевые слова для поиска. Также хотелось бы узнать о встраивании самих файлов с JavaScript кодом или других (возможно картинок) в спец. секцию исполняемого файла. Вот что нашел по данной теме: ссылка1, ссылка2, ссылка3 Получается после доставания из ресурсов фаил необходимо сохранить где-то. В приведенной Вами реализации, видимо, он сохраняется в оперативной памяти? Это сообщение отредактировал(а) TheDestroyer - 27.5.2009, 15:10 |
|||
|
||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Самый простой метод - взять все исходные файлы от zlib и добавить их в проект. Метод посложнее - сделать из них статическую библиотеку (в VS это специальный тип Win32 проекта - Static Library) и ее прилинковать к программе
Это сообщение отредактировал(а) xvr - 27.5.2009, 15:04 |
||||||
|
|||||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Удалось сделать статическую библиотеку и прилинковать ее к проекту.
Для этого пришлось сделать изменения в исходниках zlib (найдено в инете):
Также получилось засунуть zip фаил в ресурсы и достать из него текстовые файлы! А как достать, например, картинку из этого zip архива, чтобы показать ее на страничке сайта? Также хочется вынести функцию динамической генерации страничек в отдельную функцию в отдельном файле, т.к. она будет довольно большая. Т.е. сделать функцию void WEB_Server::web_process() {} в отдельном файле web_process.cpp. Делал так: 1. Создал фаил web_process.h в нем объявил WEB_Server::web_process(); , в web_process.cpp сделал #include "web_process.h". В web_process.h сделал #include "web_process.h". При компиляции вылетает куча ошибок о повторном определении функций и т.д. 2. Объявляю web_process() в web_server.h. Но надо как-то укзать что она находится в другом файле. Сответственно делаю в web_server.cpp #include "web_process.cpp". Но при компиляции вылезает ошибка, что в web_process.cpp WEB_Server: не является именем класса или пространства имен. Т.е. не видит класса WEB_Server. Подскажите, плз, как вынести функцию void WEB_Server::web_process() {} в отдельный фаил. |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Так же, как и текстовые. Файлы они и в африке файлы
Нужно в описании класса WEB_Server (в web_server.h) добавить вашу функцию web_process() Ее тело можно расположить в отдельном файле (например в web_process.cpp) В начале web_process.cpp надо сделать #include "web_server.h" |
||||
|
|||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Делаю так, но при компиляции в случае если прописать в web_process.cpp #include "web_server.h" высыпает больше 100 синтаксических ошибок в файле tcp_server.h. Напомню, что в начале файла web_server.h стоит #include "tcp_server.h". Видимо надо прядок includ-ов как-то поменять. Это сообщение отредактировал(а) TheDestroyer - 28.5.2009, 14:18 |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
В самом начале web_process.cpp нужно написать #include "StdAfx.h" (самой первой строкой)
|
||||
|
|||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо, получилось, правда пришлось перенести некоторые объявления из web_server.cpp в web_server.h.
Столкнулся с проблемой: Есть моменты, когда необходимо передавать клиенту информацию несколько раз (или в цикле). Например, идет какой-то процесс и пишет свой лог, этот лог необходимо выдавать по мере его появления. В php делал так:
Т.е. делал вывод в цикле, в браузер приходило все сразу как только появлялось в пайпе вывода. Здесь же пробую делать так:
В логе сервера появляется ошибка: Connection reset by network layer (11138616) Видимо, сервер закрывает соединение сразу после отсылки информации. А как сделать вывод в браузер информации в реальном времени, на подобии примера на php? |
||||
|
|||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
||||
|
||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Угу. Система расчитанна на отправку данных одним куском. Она проставляет размер данных в соотвествующем поле заголовка (Content-Length) и закрывает соединение после отправки
|
||||||
|
|||||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
С chunked пока не удалось реализовать частичную передачу, оставил вариант
Есть необходимость передавать на сервер файлы. Выдаю клиенту форму
Как осуществить прием файлов? |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Взять полновесный WEB сервер У меня где то были сорцы, которые этим занимались, но это еще столько же кода, сколько там уже есть В общем смотреть RFC с описанием MIME кодирования |
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Да, уже копаю в сторону парсинга multipart/form-data.
Нашел http://www.oreillynet.com/onjava/blog/2006...multiparts.html. http://pocoproject.org/download/, там много инструменов для работы с сетью (в частности class MultipartReader), но использование этой библиотеки означает, что появятся дополнительные файлы помимо исполняемого файла, и не хочется бросать то, что уже сделано, по идее остается добавить только парсинг multipart/form-data для закачки файлов на сервер. Если все-таки найдутся сорцы, то буду признателен. Это сообщение отредактировал(а) TheDestroyer - 1.6.2009, 23:35 |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Увы, сорцы похоже канули в лету
|
|||
|
||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
С закачкой файлов пока не разобрался. Но появились вопросы:
1. Как указать кодировку в которой выдавать браузеру текст? Я использую JavaScript (XMLHttpRequest), при обращении к этой функции в браузере (IE) возникает ошибка ("Ошибка c00ce56e."), поиск показал, что используется неправильная кодировка. Для cp-1251 так?
А как для UTF-8 ? 2. Проблема с редиректом. Использую функцию A.send_redir(redirect_url). В IE редирект проходит нормально, а в FireFox просто выдается весь текст страницы на белом фоне (т.е. воспринимается как plaintext). Посмотрел в FireBug в FireFox, там такая картина:
т.е. получается, что head уже отправлен браузеру и все что я отправляю далее считается телом страницы (первые 3 строки FireFox вставил сам, отправленный мной текст начинается с "<html><head> <style type=..."). Как правильно делать редирект? Это сообщение отредактировал(а) TheDestroyer - 24.6.2009, 18:12 |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Для указания кодировки используется поле заголовка Content-Type:, параметр charset=. Сервер автоматически выставлял CP1251 для текстовых файлов (см HTTP_SendAns::send_file_data)
Редирект можно делать специальными кодами возврата (30х) (см закоментареную часть в HTTP_SendAns::send_redir), но это не работало на некоторых проксях Поэтому редирект делается через заголовок HTML страницы, META http-equiv Refresh. Т.е. редирект делается самим браузером путем немедленной перезагрузки страницы с другого URL
|
|||
|
||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Сначала начал делать редирект сам, потом вспомнил, что видел уже это в коде, в итоге оставил как есть в HTTP_SendAns::send_redir, похоже это самый лучший вариант. Проблема была не в редиректе...
А вот проблему с IE и Ajax пока не решил. FF нормально работает, а IE постоянно выдает ошибку "Ошибка c00ce56e." Похоже нашел решение: http://forum.vingrad.ru/forum/topic-237305...t-explorer.html с 4го поста снизу. Идея в том, чтобы выдавать на аякс запрос в кодировке UTF-8. Как перекодировать отправляемый браузеру текст в эту кодировку? С помощью setlocale( LC_ALL, ... )? Это сообщение отредактировал(а) TheDestroyer - 29.6.2009, 00:33 |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Сервер отправляет содержимое строки 'как есть', никаких перекодировок не производится. Что бы это было UTF-8, исходная строка должна быть в UTF-8. Саму строку можно перекодировать чем угодно (например libiconv). Еще надо изменить кодировку в заголовке ответа (об этом уже писал)
|
||||
|
|||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Спасибо за наводку на libiconv. Сделал чтобы сервер выдавал текст в UTF-8.
Возникла следующая проблема: если сервер обрабатывает запрос одного пользователя, то второй уже не может зайти на сайт (на данном сервере). Есть режим работы когда пользователю на страницу долго грузится результат работы некоторых приложений, в этом случае на сайт удается зайти только после того, как все операции будут закончены. Т.е. получается что вся работа с сокетом выполняется в одном потоке.
run - функция прослушивания сокета. Как сделать так, чтобы каждому пользователю выделялся свой поток чтобы они могли работать одновременно? Вот функция обработки сокета:
Видимо, надо запускать поток для обработки process_accept(s) для каждого пользователя (а, наверное, правильнее говорить сеанса). Но тут проблема - в одном сеансе множество запросов (текст, картинки и т.д.). Как тут правильно поступить? Также возник вопрос как запустить сервер на определенном адресе, если, например, у компьютера несколько сетевых карт? |
||||
|
|||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Этот сервер намеренно был сделан single thread - для упрощения жизни (не надо связываться с синхронизацией обращений к серверным скриптам и данным для WEB страниц). Кроме того, специфика приложения - это был WEB интерфейс к программе (вместо GUI).
Если нужно многопоточное приложение, то поток надо заводить в методе WEB_Server::process_accept - все его содержимое запускать в потоке. Количество одновременно запущенных потоков можно (и даже нужно) ограничить - например сделать пул нитей, и отдавать запрос в нить из пула. По окончании обработки нить возвращать в пул. Всю синхронизацию придется добавлять (например через критические секции)
Строка 13 в tcp_server.cpp:
|
||||
|
|||||
| TheDestroyer |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Чтобы добавить многопоточность делаю так:
фаил tcp_server.cpp:
Пытался запустить поток аналогично потоку с обработкой сокета (через RUN_MAIN), но вылезают ошибки о неправильных объявлениях... Тогда решил работать с _beginthread напрямую. К сожалению просто так в функцию, передаваемую в _beginthread параметры не передашь. Да еще эта функция должна быть типа void и иметь параметр типа (void *param) . Примеры смотрел здесь: http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.71).aspx http://www.rsdn.ru/forum/cpp/4612.flat.aspx http://www.gamedev.net/community/forums/to...topic_id=448462 В борланде было проще - указал на запуск функции в отдельном потоке и все функции которые вызываются из нее тоже запускаются в том потоке, и все без преобразования типов передаваемых параметров и т.д. Может и тут так можно? Пришлось сдеделать static функции: фаил web_server.h:
фаил web_server.cpp - добавил функции с _m на конце (multithread) аналогичные их оригиналам. Только, наверное, прийдется им передавать параметры также как и в static void process_accept_m(void *sv). Пока до этого не дошел.
При компиляции ругается на то, что
Здесь это строка 11. Неужели прийдется делать все вызываемые далее функции статическими? Может у меня неправильный подход? Далее, критическими секциями, видимо, прийдется защитить, переменные которые используются в программе глобально? Это сообщение отредактировал(а) TheDestroyer - 30.6.2009, 20:17 |
||||||||
|
|||||||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Подход в корне не верный. Обработку надо делать в коде WEB_Server::process_accept
Например так
Далее - все обращения из бывшего WEB_Server::process_accept к общим ресурсам (в первую очередь - поиск и загрузка файлов) должны быть защищены критическими секциями Далее - эта реализация будет создавать по отдельному thread'у на каждый запрос. При большом числе запросов сервер может помереть |
|||
|
||||
| TheDestroyer |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
Класс, я замучался с этими потоками. Спасибо огромное.
Если несложно пояснить: здесь добавлена структура RunInfo, в ней есть RunInfo(SOCKET s1, WEB_Server* sl) :s(s1), self(sl) {}. Это инициализация структуры? Похоже на конструктор. По поводу защиты критическими секциями. Видимо при запросе от клиента все сводится к функции void WEB_Server::process_file(HTTP_SendAns &A, string fname). А там либо генерация кода страницы, либо подгрузка файлов из ресурсов. Достаточно ли защитить подгрузку файлов следующим образом: фаил web_server.cpp:
фаил zipfile.cpp:
Пример с критическими секциями смотрел здесь: http://www.cyberguru.ru/programming/cpp/mu...ntro-page2.html В find_resource будут защищены все переменные что во вложенном в нее вызове функции или только одна переменная res? Где лучше объявить CRITICAL_SECTION cs чтобы использовать в файлах zipfile.cpp и web_server.cpp? |
||||
|
|||||
| xvr |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
В С++ структуры и классы - это одно и то же (отличается только спицификатор доступа по умолчанию - для структуры public, для класса - private). Так что это конструктор и есть
InitializeCriticalSection( &cs ); нужно вынести из WEB_Server::process_accept и поместить куда то на самый верхний уровень - ее нужно вызвать ТОЛЬКО 1 раз до первого использования самой критической секции
(фаил zipfile.cpp):
|
||||||||||
|
|||||||||||
| TheDestroyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 112 Регистрация: 5.11.2007 Репутация: нет Всего: нет |
С многопоточностью вроде разобрался, спасибо.
Обнаружилась проблема: если я передаю GET методом на веб сервер строку типа "qwe%20-qwe%20+qwe", то пропадает знак "+". Стал разбираться, обнаружил:
Чем грозит переключение supp_plus в false? Как правильно обработать этот момент? |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
При кодировании URL пробелы заменяются на знак '+' (HTTP требует). Если нужен пробел лучше передавать его как %31
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |