Micro Web Server DLL Что это и для чего это? 1) Это небольшой веб сервер реализованный в виде DLL 2) Может использовать как добавочная нагрузка на разного рода программы, где необходим свой простенький веб сервер, преимущественно для скачевание файлов. А также можно сделать его полезной нагрузкой шпионских программ или других ползучих гадов ) Характеристики: 1) чистый размер DLL - 4608 2) язык программирования - С++ 3) среда разработки - MS Visual Studio 2008 Pro 4) 2 функции - остановка сервера и запуск сервера 5) Поддерживаемые ОС - Windows 98SE - Windows 7 6) Возможность использования в любых программах на любых языках (ASM, Delphi, C, C++, VB и другие компилируемые языки) 7) Сокетная система - WinSock2 8) зависимость от DLL - WS2_32.DLL, KERNEL32.DLL, USER32.DLL. Другими словами - всё стандартное, всё системное. Возможности: 1) неограниченное кол-во работающих параллельно серверов (сколько система позволит) 2) Запуск и остановка любого сервера в любое время 3) задание порта для сервера 4) задание таймаута на получение команды от клиента 5) установка своей корневой диры для каждого сервера 6) задание максимального кол-ва пользователей одновременно обрабатываемых сервером. 7) установку размера буфера при отдаче файлов. (но не менее 1024 байт) 8) максимальный поддерживаемый размер файла - сколько позволит винда. Теоретически должно работать с файлами > 4 гигов 9) показ содержимого папки 10) поддержка русскоязычных названий папок и файлов. Теоретически вообще любые кодировки должны пахать, потому что используется widechar. Чего не умеет: 1) никакие запросы кроме GET не поддерживаются 2) нет поддержки докачки файлов. 3) нет поддержки файлов размером больше 2 гигов. 4) никакие php, perl и прочие cgi не поддерживаются 5) сервер настроен так, что все файлы он отдает на скачевание а не на показ. т.е. я поставил application/octet-stream для всех типов файлов. Но по желанию каждый может изменить. Функции DLL function StartServer(var id : dword; ip : dword; port : word; MaxClients : integer; TimeOut : dword; BufSize : dword; MainDir : pwidechar):dword; Функция возвращает результат запуска сервера. Константы описаны ниже. Параметры: id - в переменную будет записан дескриптор сервера ip - сетевой интерфейс на котором будет слушаться порт. 0 - на всех. port - порт для сервера MaxClients - макс число одновременно подсоединенных клиентов к данному серверу TimeOut - таймаут на получение команды от клиента в миллисекундах. т.е. 1000 = 1 сек BufSize - размер буфера при передаче файлов MainDir - корневая папка сервера function StopServer(id : dword) : dword; - остановка сервера. id - дескриптор сервера Пример использование в Delphi Разместить DLL в папке с программой. Code: const // коды ошибок SERVER_STATUS_OK = $FFFFFFF0; SERVER_STATUS_FOLDER_ERROR = $FFFFFFF1; SERVER_STATUS_CREATE_SOCKET_ERROR = $FFFFFFF2; SERVER_STATUS_BIND_ERROR = $FFFFFFF3; SERVER_STATUS_LISTEN_ERROR = $FFFFFFF4; SERVER_STATUS_ALLOC_MEM_ERROR = $FFFFFFF5; SERVER_STATUS_CREATE_THREAD_ERROR = $FFFFFFF6; SERVER_STATUS_ID_ERROR = $FFFFFFF7; // остановка сервера function StopServer(id : dword) : dword; stdcall; external 'WebServ.dll'; // запуск сервера function StartServer(var id : dword; ip : dword; port : word; MaxClients : integer; TimeOut : dword; BufSize : dword; MainDir : pwidechar):dword; stdcall; external 'WebServ.dll'; var Server_1 : dword; Server_2 : dword; procedure TForm1.Button1Click(Sender: TObject); var status : dword; begin // запустить сервер. status := StartServer(Server_1, 0, 666, 10, 30000, 4096, 'c:\'); if status <> SERVER_STATUS_OK then begin ShowMessage('Server 1 Start Error. Code = ' + inttohex(status, 8)); end; status := StartServer(Server_2, 0, 667, 10, 30000, 4096, 'd:\'); if status <> SERVER_STATUS_OK then begin ShowMessage('Server 2 Start Error. Code = ' + inttohex(status, 8)); end; end; // остановка procedure TForm1.Button2Click(Sender: TObject); var status : dword; begin status := StopServer(Server_1); if status <> SERVER_STATUS_OK then begin ShowMessage('Server 1 Stop Error. Code = ' + inttohex(status, 8)); end; status := StopServer(Server_2); if status <> SERVER_STATUS_OK then begin ShowMessage('Server 2 Stop Error. Code = ' + inttohex(status, 8)); end; end; Пример использование в С++ Для С++ по подобной системе. Code: #define SERVER_STATUS_OK 0xFFFFFFF0 #define SERVER_STATUS_FOLDER_ERROR 0xFFFFFFF1 #define SERVER_STATUS_CREATE_SOCKET_ERROR 0xFFFFFFF2 #define SERVER_STATUS_BIND_ERROR 0xFFFFFFF3 #define SERVER_STATUS_LISTEN_ERROR 0xFFFFFFF4 #define SERVER_STATUS_ALLOC_MEM_ERROR 0xFFFFFFF5 #define SERVER_STATUS_CREATE_THREAD_ERROR 0xFFFFFFF6 #define SERVER_STATUS_ID_ERROR 0xFFFFFFF7 ULONG __stdcall StartServer(ULONG* id, ULONG ip, USHORT port, LONG MaxClients, ULONG TimeOut, ULONG BufSize, wchar_t * MainDir) ULONG __stdcall StopServer(ULONG id) ..................... ULONG Server; StartServer(&Server_1, 0, 666, 10, 30000, 4096, L"c:\\"); ....................... На последок Если компилить как exe то размер будет 3,5 кила. В принципе работает норм. Покрайней мере при тестировании. Кто пробовал, отпишите. В архиве вы найдете файлы: WebServ.cpp - исходник DLL WebServ.def - вспомогательный файл WebServ.dll - откомпиленная DLL WebServ.h - хидер WebServ.vcproj - файл проекта (С) SLESH 2009 )
жаль что максимальный поддерживаемый размер файла - 2 гига. Серьезный порнофильм уже не скачаешь с такими ограничениями
ахахха. Да, bons, не думал, что ты настолько суров, чтобы ломать людей, ставить им веб-серваки, и все это - только для того, чтобы тырить у них порно! <релиз как всегда на высоте, +1 в золотой фонд ачата> очень не часто можно найти такие вещи с сурсами *thumbs_up* *respect* скоро можно будет открывать целый подраздел в кодинге - "статьи\релизы". И это будет true
2 bons если тебе нужны файлы оооочень большого размера, то можеш сам ыбстро подправить. у меня в 2-х местах юзается функция GetFileSize без указания адреса буфера для старшей части размера. По этому получаю только младшую его часть, ограниченную 4-мя гигами. Вообще тут чтото непонятное. Одна дока пишет что 2 гига максимум, другая 4 гига. Но вообще, сейчас подправлю и перезалью.
когда-то писал подобную вещь для подобных целей, только это был ftp-сервер и на делфи(тоже в виде DLL). И знаете, у 95% это единственное ценное на винте. По теме: slesh у вас там странный очень код: Code: len = recv(sock, tmp, 4096 - fulllen, 0); // считаем данные if (len > 0) // если данных больше 0 { tmp = (char*)((ULONG)tmp + (ULONG)len); // переместим указатель в нутри буфера fulllen += len; // сумарный размер } вот здесь принимаются данные и по логике переменная fulllen вполне может оказаться равной 4096. А здесь Code: input_buf[fulllen] = 0x00; в таком случае будет обнулен уже не элемент массива input_buf а нечто другое. А содержимое input_buf уже будет не ASCIIZ-строкой. Возможно это фигня и ничего плохого из-за этого не случится(я не смотрел дальше) но все же неприятно Еще не совсем понятно зачем переписывать стандатртную функцию strstr. Начало функции my_strstr мне тоже нравится Code: char *cp = (char *) str1; Зачем вы тут приводите типы? обе переменные типа char* и приведение тут совсем не нужно. И не только тут. Например строчку Code: tmp = (char*)((ULONG)tmp + (ULONG)len); легко можно записать так: Code: tmp += len; Ну я детально не разбирал, наверно там еще есть ченить интересное. А так вообще сервер норм, пригоден для тыренья порнухи в локалке, да. Только опять жже почему вы все делаете на потоках? microsoft предоставила уйму API чтобы вы так не делали: WSAEventSelect, WSAAsyncSelect и много других. А вы вот предпочитаете юзать самую примитивную модель сетевого приложения PS вы тут писали: это не С++ а С
2 bons 1) там не странный код, а код который считывает http запрос до того как встретится \r\n\r\n при условии что максимум 4096 можно считать. Код построен таким образом, чтобы учесть тот факт что запрос может быть разбит на небольшие части. 2) с input_buf[fulllen] = 0x00; ты прав. Может быть глюк. но при условии что будут посланы именно 4096 байт. мне достаточно сделать input_buf[fulllen-1] = 0x00; всё равно мне конец не нужен или ограничить чтение 4095 байтами 3) char * my_strstr(char * str1, char * str2) - взята из исходников CRT либы VS 2008 Pro когда юзал либу, то почему-то кода становилось больше, чем когда извлек эту функцию. По поводу кривизны функции этой - пиши жалобу в MS может исправят ) 4) не привык както к асинхронным сокетам, по этому использую по старинке всё) Тем более что тут это не критично. т.к. юзать больше 1-2 серваков врядли ктото будет. А работа с сетью - если будет качаться большой файл при большом буфере и малой скорости коннекта, то тут без потока не обойтись.
2 bons ты думаешь я об этом не знаю? Впервые столкнулся с такой проблемой в DDK когда в дровах такая запись не подходила. И дело там было в том, что tmp += len; и tmp = (char*)((ULONG)tmp + (ULONG)len); давали совершенно разные результаты. Юзался тогда компилятор MS DDK XP. C тех пор начал везде писать код в подобном виде я прекрасно знаю что я пишу в Сишном стиле а не С++ Сказано это было потому что компилятору даются указания что это С++ код а не С Хотя будет компилиться нормально и как Си
А я как раз изучаю работу с сокетами! Прям подарок для меня Респект, а так же отдельное спасибо за пример работы с Delphi.
2 Sams если ты изучаеш делфи, то лучше найти какойнить проект который написан на делфи, а не на Си, чтобы потом небыло у тебя путаници, которая происходит из-за того что в Си больше юзаются указатели.