Листинг модуля OptionsUnit.pas

advertisement
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
БРЯНСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра «Информатика и программное обеспечение»
КУРСОВАЯ РАБОТА
по курсу
«Сети ЭВМ и телекоммуникации»
Тема: «Разработка простого http сервера»
Выполнил:
студент гр. 05-САПР
Лазаренко А.В. _________
Руководитель:
Трубаков А.О.___________
БРЯНСК 2008
СОДЕРЖАНИЕ
1. ЗАДАНИЕ НА РАЗРАБОТКУ ................................................................................ 3
2. ВВЕДЕНИЕ ............................................................................................................... 4
3. ОСНОВНОЙ РАЗДЕЛ ............................................................................................. 5
4. ТЕСТИРОВАНИЕ РАБОТОСПОСОБНОСТИ ПРИЛОЖЕНИЯ ...................... 13
Листинг модуля OptionsUnit.pas ............................................................................... 15
Листинг модуля FuncUnit.pas.................................................................................... 16
Листинг приложения.................................................................................................. 22
5. ЗАКЛЮЧЕНИЕ ...................................................................................................... 27
6. СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ.................................................... 28
2
1. ЗАДАНИЕ НА РАЗРАБОТКУ
Реализовать простейший http-сервер. Сервер должен корректно
обрабатывать GET-запросы и посылать клиенту запрашиваемые файлы. Должна
быть предусмотрена обработка исключительных ситуаций и базовых ошибок
HTTP.
3
2. ВВЕДЕНИЕ
Веб-сервер — это сервер, принимающий HTTP-запросы от клиентов, обычно
веб-браузеров, и выдающий им HTTP-ответы, обычно вместе с HTML-страницей,
изображением, файлом, медиа-потоком или другими данными. Веб-серверы —
основа Всемирной паутины.
Веб-сервером называют как программное обеспечение, выполняющее
функции веб-сервера, так и компьютер, на котором это программное обеспечение
работает.
В мире существует огромное количество различных веб-серверов, наиболее
известным и популярным среди которых является свободный Apache и ISS от
Microsoft. Существуют небольшие web сервера для ограниченного круга задач
(поддержка только статического контента для быстрого скачивания, встраиваемые
решения, и так далее).
Наша реализация веб-сервера пишется в учебных и образовательных целях,
поэтому излишний функционал реализован не будет. Однако написание
очередного «велосипеда» принесёт пользу автору в виде изучения работы сетевых
приложений, программирования сокетов и понимания принципа работы протокола
HTTP.
4
3. ОСНОВНОЙ РАЗДЕЛ
3.1.
Протокол HTTP
HTTP (HyperText Transfer Protocol - протокол передачи гипертекста) был
разработан как основа World Wide Web.
HTTP - это основной протокол передачи, используемый в Интернет. Первая,
широко применяемая версия HTTP, была версия 1.0. После того, как Интернет
стал стремительно развиваться, недостатки первой версии стали очевидными.
Протокол HTTP версии 1.1, используемый сегодня, исправил их, а также
значительно расширил первую версию. HTTP до сих пор не поддерживает сессии
и представляет собой простой протокол запросов - ответов. Для обеспечения
надежности, HTTP использует соединения, предоставленные транспортным
протоколом TCP/IP. HTTP спроектирован для типичного клиент-серверного
поведения.
Работа по протоколу HTTP происходит следующим образом: программаклиент устанавливает TCP-соединение с сервером (стандартный номер порта - 80)
и выдает ему HTTP-запрос. Сервер обрабатывает этот запрос и выдает HTTPответ клиенту.
5
3.2
Обзор HTTP
В «сердце» web находится протокол передачи гипертекста (HTTP – HyperText
Transfer Protocol), являющийся протоколом прикладного уровня. Описание HTTP
можно найти в RFC 1945 и RFC 2616. Протокол HTTP реализуется с помощью
двух программ: клиента и сервера, которые, находясь на разных оконечных
системах, обмениваются HTTP-сообщениями.
В 1997 году практически все web-браузеры и web-серверы стали
поддерживать протокол HTTP версии 1.0, описанный в документе RFC 1945. В
1998 году начался переход к версии 1.1, которая была описана в RFC 2616. Версия
1.1 имеет обратную совместимость с версией 1.0, т.е. любой сервер и браузер,
использующий версию 1.1, может а полной мере взаимодействовать с браузером
или сервером, поддерживающий версию 1.0.
Как HTTP 1.0, так и HTTP 1.1 используют TCP в качестве протокола
транспортного уровня. HTTP-клиент сначала устанавливает TCP-соединение с
сервером,
а
после
создания
соединения
клиент
и
сервер
начинают
взаимодействовать с протоколом TCP через механизм сокетов. Клиент посылает
запросы и принимает ответы через свой интерфейс сокетов, а сервер использует
интерфейс сокетов для получения запросов и их выполнения.
Протоколу HTTP не нужно контролировать надежность передачи данных –
вся «черновая» работа будет проделана протоколом TCP и протоколами более
низкого уровня.
Необходимо отметить, что после завершения обслуживания клиентов сервер
не сохраняет о них никакой информации. Если, например, какой-либо клиент
сделает два запроса одного и того же ресурса подряд, сервер выполнит их, не
выдав клиенту никакого сообщения о дублирующемся запросе. Говорят, что
протокол HTTP является протоколом без запоминания состояния (stateless
protocol) соединения.
6
3.3
Постоянные и непостоянные соединения
Протокол HTTP поддерживает постоянные и непостоянные соединения
(версия 1.0 – только непостоянные). При непостоянном соединении протокол TCP
получает только один объект, а при постоянном соединении (для версии 1.1
используется по умолчанию) – все объекты. Разумеется, клиенты и серверы с
поддержкой HTTP 1.1 можно настроить и для непостоянного соединения.
3.3.1 Непостоянные соединения
Рассмотрим, каким образом осуществляется передача объекта в web-сервера
к клиенту в случае непостоянного HTTP-соединения. Будем считать, что с сервера
мы хотим загрузить индексную html-страничку и десяток графических файлов.
Взаимодействие между клиентом и сервером будут состоять из следующих
шагов:
1.
HTTP-клиент инициирует TCP-соединение с сервером через порт, на
котором работает HTTP-сервер (обычно 80).
2.
Клиент посылает запрос серверу через сокет, выделенный TCP-
соединению, установленному на шаге 1.
3.
Сервер
получает
запрос
через
сокет,
ассоциированный
с
установленным соединением, извлекает запрашиваемый объект, формирует ответ
и отсылает его клиенту.
4.
HTTP-сервер
закрывает
TCP-соединение
(на
самом
деле
окончательный разрыв соединения происходит только после того, как сервер
получит подтверждение об успешном приеме ответа клиентом).
5.
Клиент принимает ответ от сервера и завершает TCP-соединение.
6.
Шаги 1-5 повторяются для всех остальных объектов, которые желает
получить клиент.
Важно отметить, что HTTP-протокол никаким образом не связан с тем, как
браузеры
визуализируют
полученную
информацию.
Описанный
пример
относится к случаю непостоянного соединения. При большом количестве
7
запрашиваемых объектов многократно устанавливается и завершается TCPсоединение. Каждая сессия обмена по установленному соединению состоит из
единственного запроса и ответа.
Данная модель может использоваться для параллельной загрузки объектов,
однако для этого параллельно устанавливаются несколько соединений. На
практике браузеры устанавливают одновременно 5-10 параллельных TCPсоединений.
Рис.1. Установка каталога с данными сайта
Одним из немаловажных параметров при сетевом клиент-серверном
взаимодействии является время
от начала запроса до полного получения
результата. Воспользуется понятием время оборота (Round-Trip Time, RTT), т.е.
временем, которое требуется пакету малой длины для передачи от клиента к
8
серверу и обратно. Время оборота включает в себя задержку распространения,
ожидания и обработки. Оценка времени получения результата от сервера
клиентом приведена на рис. 1.
3.3.2 Постоянные соединения
Непостоянные соединения обладают рядом недостатков. Прежде всего, для
каждого запрашиваемого объекта должно устанавливаться новое соединение. При
этом следует учитывать, что каждое TCP-соединение требует выделение буферов
приема и отправки, а также иных служебных переменных как на стороне клиента,
так и на серверной стороне. Также принимая во внимание тот факт, что в
реальной ситуации HTTP-сервера обрабатывают десятки и сотни запросов
одновременно, подобная схема работы требует значительных ресурсов и
повышает нагрузку на сетевой канал.
В случае использования постоянного соединения сервер не закрывает TCPсоединение после ответа на запрос клиента, а позволяет клиенту послать в рамках
ранее установленного соединения очередные запросы. На практике применяется
смешанная схема работы, а именно для TCP-соединения устанавливается таймаут,
по истечении которого, если соединение не используется, происходит его
закрытие. Это задается параметром HTTP-заголовка «Keep-Alive: N», где N–
целочисленный интервал в секундах.
Постоянные соединения можно разделить на 2 класса: с без конвейеризацией
и с конвейеризации. В первом случае клиент посылает новый запрос серверу
только после завершения приема очередного объекта, а во втором случае –
запросы могут посылаться до окончания приема предыдущего объекта. Это
достаточно легко реализуется, если учитывать, что TCP-соединение полностью
дуплексное.
Вариант работы с конвейеризацией является наиболее эффективным и
позволяет достигать максимальной производительности в передаче данных между
клиентом и сервером.
9
3.4
Структура HTTP-запроса
HTTP-запрос состоит из заголовка запроса и тела запроса, разделенных
пустой строкой. Тело запроса может отсутствовать.
Заголовок запроса состоит из главной (первой) строки запроса и
последующих строк, уточняющих запрос в главной строке.
Метод (команда HTTP):
GET - запрос документа. Наиболее часто употребляемый метод
HEAD - запрос заголовка документа. Отличается от GET тем, что выдается
только заголовок запроса с информацией о документе. Сам документ не выдается.
POST - этот метод применяется для передачи данных CGI-скриптам. Сами
данные следуют в последующих строках запроса в виде параметров.
PUT - разместить документ на сервере. применяется, когда пользователь
заполняет формы, например, при вводе логина и пароля во время авторизации на
почтовом сервере.
Метод HEAD аналогичен GET за тем исключением, что при получении
запроса с методом HEAD сервер формирует ответ, но не осуществляет пересылку
объекта. Одно из применения данного метода – тестирование и поиск ошибок.
Версия протокола - версия протокола HTTP, с которой работает клиентская
программа.
Таким образом, простейший HTTP-запрос может выглядеть следующим
образом:
GET / HTTP/1.0
Здесь запрашивается корневой файл из корневой директории web-сервера.
Строки после главной строки запроса имеют следующий формат:
Параметр: значениe.
Таким образом задаются параметры запроса. Это является необязательным,
все строки после главной строки запроса могут отсутствовать; в этом случае
сервер принимает их значение по умолчанию или по результатам предыдущего
запроса (при работе в режиме Keep-Alive).
Соединение (Connection) - может принимать значения Keep-Alive и close.
10

Keep-Alive ("оставить в живых") означает, что после выдачи данного
документа соединение с сервером не разрывается, и можно выдавать еще запросы.
Большинство браузеров работают именно в режиме Keep-Alive, так как он
позволяет за одно соединение с сервером "скачать" html-страницу и рисунки к
ней. Будучи однажды установленным, режим Keep-Alive сохраняется до первой
ошибки или до явного указания в очередном запросе

close ("закрыть") - соединение закрывается после ответа на данный
запрос.
11
Формат HTTP-ответа
3.5
Формат ответа очень похож на формат запроса: он также имеет заголовок и
тело, разделенное пустой строкой. Заголовок также состоит из основной строки и
строк параметров, но формат основной строки отличается от таковой в заголовке
запроса. Основная строка запроса состоит из 3-х полей, разделенных пробелами:
Версия протокола - аналогичен соответствующему параметру запроса.
Код ошибки - кодовое обозначение "успешности" выполнения запроса. Код
200 означает "все нормально" (OK).
Словесное описание ошибки - "расшифровка" предыдущего кода. Например
для 200 это OK, для 500 - Internal Server Error.
Наиболее употребительные параметры http-ответа:
Connection - аналогичен соответствующему параметру запроса. Если сервер
не поддерживает Keep-Alive (есть и такие), то значение Connection в ответе всегда
close.
В зависимости от значения Content-Type браузер воспринимает ответ как
HTML-страницу, картинку gif или jpeg, как файл, который надо сохранить на
диске, или как что-либо еще и предпринимает соответствующие действия.
Значение Content-Type для браузера аналогично значению расширения файла для
Windows.
12
4. ТЕСТИРОВАНИЕ РАБОТОСПОСОБНОСТИ
ПРИЛОЖЕНИЯ
Программа имеет консольный интерфейс. При запуске открывается обычное
консольное окно, и программа ожидает соединений (рис.2).
Рис.2. Работа программы в режиме ожидания соединения
Откроем броузер и наберём http://127.0.0.1 или http://localhost в адресной
строке. Скорее всего мы получим ошибку 404 (Файл не найден). Это связано с
тем, что сервер обращается по умолчанию к каталогу C:\ServerDirectory,
заданному в файле настроек config.ini по умолчанию. Нам необходимо создать
этот каталог и положить туда какой-нибудь index.html файл или любые другие
файлы, и попробовать их скачать или просмотреть, после чего нам выведется
страница, представленная на рис.3. А окно работы программы (рис.4.) будет
содержать в себе: IP-адрес компьютера, запросившего файл, короткое имя
запрашиваемого файла (без имени каталога C:\ServerDirectory),дату и время когда
был произведен запрос, а также слово Success или Error (в случае успешной
загрузки файла или ошибки соответственно).
13
По умолчанию если не указано имя файла и URL заканчивается на / этот URL
рассматривается как имя директории, из которой берётся файл index.html.
Рис.3. Запрос html-страницы
Рис.4. Работа программы при постоянном соединении
14
Листинг модуля OptionsUnit.pas
unit OptionsUnit;
interface
uses IniFiles;
type
TOptions=record
BufferSize:word;
Port:word;
ServerRoot, StartPage:string;
ConsoleOutput, FileOutput:boolean;
OutputFName, OutputDirectory:string;
end;
procedure LoadOptions(FName:string; var Opt:TOptions);
implementation
procedure LoadOptions(FName:string; var Opt:TOptions);
var Ini:TIniFile;
begin
Ini:=TIniFile.Create(FName);
Opt.BufferSize:=Ini.ReadInteger('Options','BufferSize',2048);
Opt.Port:=Ini.ReadInteger('Options','Port',80);
Opt.ServerRoot:=Ini.ReadString('Options','ServerRoot','C:\ServerDirectory');
Opt.StartPage:=Ini.ReadString('Options','StartPage','index.html');
Opt.ConsoleOutput:=Ini.ReadBool('Options','ConsoleOutput',true);
Opt.FileOutput:=Ini.ReadBool('Options','FileOutput',false);
Opt.OutputFName:=Ini.ReadString('Options','OutputFName','');
Ini.Free;
end;
end.
15
Листинг модуля FuncUnit.pas
unit FuncUnit;
interface
uses Classes, WinSock, OptionsUnit, Windows;
var LogFile:TextFile;
procedure LogError(LogStr:String; Options:TOptions);
function ReadSockStr(s:TSocket; var ResStr:string; Options:TOptions):integer;
function StrToFileName(InputStr:string; var FName:string; Options:TOptions):word;
procedure SendCode(s:TSocket; ErrorCode:integer; FName:string);
procedure SendFile(s:TSocket; FName:string; Options:TOptions);
implementation
uses SysUtils;
const HTTP200='HTTP/1.1 200 OK'+#13#10;
HTTP404='HTTP/1.1 404 Not Found'+#13#10;
HTTP414='HTTP/1.1 414 Request-URI Too Long'+#13#10;
HTTP500='HTTP/1.1 500 Internal Server Error'+#13#10;
HTTP404HTML='<html><head><title>Error 404!</title></head><body><b>Ошибка 404: Файл
не найден!</b></body></html>'+#13#10;
HTTP414HTML='<html><head><title>Error 414!</title></head><body><b>Ошибка 414:
Запрашиваемый URI слишком длинен!</b></body></html>'+#13#10;
16
HTTP500HTML='<html><head><title>Error 500!</title></head><body><b>Ошибка 500:
Внутренняя ошибка сервера!</b></body></html>'+#13#10;
var SERVERNAME:string='Server: SimpleHTTPserver'+#13#10;
CLOSECONN:string='Connection: close'+#13#10;
SPACESTR:string=#13#10;
procedure LogError(LogStr:String; Options:TOptions);
begin
if Options.ConsoleOutput=true then
WriteLn(LogStr);
if Options.FileOutput=true then
WriteLn(LogFile,LogStr);
end;
function GetFileSize(FileName:string):Integer;
var
InfoFile: TSearchRec;
AttrFile: Integer;
ErrorReturn: Integer;
begin
AttrFile := faAnyFile;
ErrorReturn := FindFirst(FileName, AttrFile, InfoFile);
if ErrorReturn <> 0 then
Result := -1
else
Result := InfoFile.Size;
FindClose(InfoFile);
17
end;
function ReadSockStr(s:TSocket; var ResStr:string; Options:TOptions):integer;
var vSize, BufSize:Integer;
aBuff:array of Char;
begin
BufSize:=8192;
vSize:=SizeOf(BufSize);
GetSockOpt(s, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize),vSize);
SetLength(aBuff, BufSize);
vSize:=recv(s, aBuff[0], BufSize, 0);
SetLength(ResStr, vSize);
lstrcpyn(@ResStr[1],@aBuff[0],Length(aBuff));
Finalize(aBuff);
Result:=vSize;
end;
function StrToFileName(InputStr:string; var FName:string; Options:TOptions):word;
var SpacePos:word;
begin
if Pos('GET ',InputStr)=1 then
begin
FName:=Options.ServerRoot+Copy(InputStr,5,Length(InputStr)-4);
SpacePos:=Pos(' ',FName);
FName:=Copy(FName,1,SpacePos-1);
FName:=StringReplace(FName,'/','\',[rfReplaceAll]);
18
FName:=StringReplace(FName,'%20',' ',[rfReplaceAll]);
if FName[Length(FName)]='\' then FName:=FName+Options.StartPage;
if Length(FName)>=Options.BufferSize-1 then
begin
Result:=414;
Exit;
end;
end
else FName:=Options.ServerRoot+'\'+Options.StartPage;
if (FileExists(FName)=false) then
begin
Result:=404;
Exit;
end;
Result:=200;
end;
procedure SendCode(s:TSocket; ErrorCode:integer; FName:string);
var TempStr, TempStrHtml, ContStr, ResStr:string;
begin
case ErrorCode of
200:begin
TempStr:=HTTP200;
ContStr:=Format('Content-Length: %d'+#13#10,[GetFileSize(FName)]);
end;
404:begin
TempStr:=HTTP404;
19
TempStrHtml:=HTTP404HTML;
ContStr:=Format('Content-Length: %d'+#13#10,[Length(HTTP404HTML)]);
end;
414:begin
TempStr:=HTTP414;
TempStrHtml:=HTTP414HTML;
ContStr:=Format('Content-Length: %d'+#13#10,[Length(HTTP414HTML)]);
end;
500:begin
TempStr:=HTTP500;
TempStrHtml:=HTTP500HTML;
ContStr:=Format('Content-Length: %d'+#13#10,[Length(HTTP500HTML)]);
end;
end;
ResStr:=TempStr+SERVERNAME+ContStr+CLOSECONN+SPACESTR;
send(s, ResStr[1], Length(ResStr), 0);
if ErrorCode<>200 then send(s, TempStrHtml[1], Length(TempStrHtml),0);
end;
procedure SendFile(s:TSocket; FName:string; Options:TOptions);
var FHandle:Integer;
FLength, IterCount, i:LongInt;
vBuff:array of Byte;
ShortFName:string;
begin
ShortFName:=FName;
Delete(ShortFName, 1, Length(Options.ServerRoot));
20
FLength:=GetFileSize(FName);
FHandle:=FileOpen(FName,fmOpenRead);
if FHandle=-1 then
begin
LogError('ERROR while opening file '+ShortFName+
' at '+DateTimeToStr(Now)+' ...', Options);
exit;
end;
SetLength(vBuff,Options.BufferSize);
IterCount:=FLength div Options.BufferSize;
for i:=1 to IterCount do
begin
FileRead(FHandle,vBuff[0],Options.BufferSize);
send(s, vBuff[0], Length(vBuff), 0);
end;
if FLength<>IterCount*Options.BufferSize then
begin
SetLength(vBuff,FLength-IterCount*Options.BufferSize);
FileRead(FHandle, vBuff[0], FLength-IterCount*Options.BufferSize);
send(s, vBuff[0], Length(vBuff), 0);
end;
Finalize(vBuff);
FileClose(FHandle);
end;
end.
21
Листинг приложения
program SimpleHTTPServer;
{$APPTYPE CONSOLE}
uses
WinSock,
SysUtils,
Windows,
FuncUnit in 'FuncUnit.pas',
OptionsUnit in 'OptionsUnit.pas';
const LISTEN_NUM=SOMAXCONN;
type PSocket=^TSocket;
var vWSAData:TWSAData;
vListenSocket,vSocket:TSocket;
Opt:TOptions;
procedure CreateLSocket(var s:TSocket; Options:TOptions);
const _on:boolean = true;
var SockName:TSockAddr;
begin
SockName.sa_family:=AF_INET;
SockName.sin_addr.S_addr:=htonl(INADDR_ANY);
SockName.sin_port:=htons(Options.Port);
22
s:=Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if s=SOCKET_ERROR then
begin
LogError('ERROR while creating socket at '+DateTimeToStr(Now)+' ...', Options);
Exit;
end;
if setsockopt(s, SOL_SOCKET, SO_REUSEADDR, PChar(@_on),
SizeOf(_on))=SOCKET_ERROR then
begin
LogError('ERROR while setting socket options at '+DateTimeToStr(Now)+' ...', Options);
Exit;
end;
if bind(s, SockName, SizeOf(TSockAddr))=SOCKET_ERROR then
begin
LogError('ERROR while binding socket at '+DateTimeToStr(Now)+' ...', Options);
Exit;
end;
if listen(s, LISTEN_NUM)<>0 then
begin
LogError('ERROR while listening at '+DateTimeToStr(Now)+' ...', Options);
Exit;
end;
end;
procedure ServerProc;
var s:TSocket;
23
ErrCode:word;
TempStr, FName, ShortFName, SuccessStr:string;
ClientAddr:TSockAddr;
ClAddrSize:integer;
begin
s:=vSocket;
ClAddrSize:=SizeOf(TSockAddr);
getpeername(s, ClientAddr, ClAddrSize);
if ReadSockStr(s, TempStr, Opt)<=0 then
begin
LogError('Server ERROR at '+DateTimeToStr(Now)+' ...', Opt);
SendCode(s, 500, FName);
closesocket(s);
exit;
end;
ErrCode:=StrToFileName(TempStr,FName,Opt);
ShortFName:=FName;
Delete(ShortFName, 1, Length(Opt.ServerRoot));
if ErrCode=200 then SuccessStr:='Success...' else SuccessStr:='ERROR...';
LogError(inet_ntoa(ClientAddr.sin_addr) +
' asked for ' +
ShortFName+
' at '+
DateTimeToStr(Now)+
24
' : '+SuccessStr, Opt);
SendCode(s, ErrCode, FName);
if ErrCode=200 then SendFile(s, FName, Opt);
closesocket(s);
end;
BEGIN
LoadOptions(ExtractFilePath(ParamStr(0))+'Config.ini',Opt);
if Opt.FileOutput=true then
try
AssignFile(LogFile,Opt.OutputFName);
if FileExists(Opt.OutputFName)=false then Rewrite(LogFile) else Append(LogFile);
except
CloseFile(LogFile);
end;
if WSAStartup($101, vWSAData)<>0 then
begin
LogError('ERROR while initializing at '+DateTimeToStr(Now)+' ...', Opt);
Write('Press <Enter>');
Readln;
Halt(1);
end;
CreateLSocket(vListenSocket,Opt);
LogError('Starting listening at '+DateTimeToStr(Now)+' ...', Opt);
25
repeat
vSocket:=accept(vListenSocket,nil,nil);
if vSocket=SOCKET_ERROR then
begin
LogError('ERROR while connecting at '+DateTimeToStr(Now)+' ...', Opt);
continue;
end;
ServerProc;
until false;
CloseFile(LogFile);
closesocket(vListenSocket);
WSACleanup;
END.
26
5. ЗАКЛЮЧЕНИЕ
Курсовая работа представляет собой программный продукт, написанный на
языке Object Pascal в ИСР Delphi 6 и пояснительную записку.
В
учебных
целях
была
разработана
реализация
HTTP
протокола,
представленная в виде простейшего веб-сервере. Изучены основные принципы
сетевого взаимодействия программ через сокеты. При этом в программе было
реализовано:
 корректная загрузка html-страниц
 возможность загрузки файлов (с сервера)
 поддержка обработки базовых ошибок
 возможность настройки сервера с помощью конфигуратора
27
6. СПИСОК ИСПОЛЬЗУЕМОЙ ЛИТЕРАТУРЫ
1. Единый указатель ресурсов. http://ru.wikipedia.org/wiki/URL
2. Hypertext Transfer Protocol – HTTP/1.1. RFC 2616
3. Йон Снейдер. Эффективное программирование TCP/IP. Питер, 2001 – 320 с.
4. Семенов Ю.А. Гипертекстный протокол HTTP. http://book.itep.ru/
4/45/http4561.htm
5. Сборник статей по программированию в среде Delphi «DelphiWorld 6.0»
28
Download