МО и НРФ
НГТУ
Кафедра программных систем и баз данных
Лабораторная работа № 4
по курсу: “Сетевые информационные технологии”
на тему “Технология клиент-сервер. Web”
Факультет: ПМИ
Группа: ПМ-02
Студентки: Калинина М.Г.
Тетерюкова А.В.
Преподаватель: Долозов Н.Л.
Петрусь В.Б.
Новосибирск
2004
1. Задание
Написать web-сервер, который должен отображать страницу данной бригады.
В качестве клиентов будет использоваться любой browser, например, Internet Explorer, Mozilla и т.п.
2. Реализация
За основу была взята программа, находящаяся на диске J:\DNL\CD\CNAIAPI.
Запуск сервера происходит с указанием номера порта из возможных номеров для протокола TCP/IP, например 2009:
http://имя_компьютера:порт, например, http://pc-204-10:2009.
Сервер находится в режиме ожидания соединения от клиента. После установления соединения сервер принимает строки от клиента, распознавая значащие: запрос на передачу клиенту какого-либо файла (команда GET). Если запрашиваемый файл существует, то сервер посылает клиенту заголовок HTTP 1.0 (в котором сообщает тип передаваемого файла и его размер), считывает сам файл и передает его содержимое клиенту. Если файла не существует или нет значащих строк, то клиенту передается сообщение об ошибке.
После передачи файла или сообщения об ошибке, сервер отключает клиента и снова возвращается в режим ожидания соединения
3. Текст программы
/* webserver.c */
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include "cnaiapi.h"
#define BUFFSIZE 256
#define SERVER_NAME "PM0209 Web Server 0.01b1"
#define ERROR_400 "<head></head><body><html><h1>Error 400</h1><p>Th\
e server couldn't understand your request.</html></body>\n"
#define ERROR_404 "<head></head><body><html><h1>Error 404</h1><p>Do\
cument not found.</html></body>\n"
int recvln(connection, char *, int);
void send_head(connection, int, int, char*);
/*----------------------------------------------------------------------* Программа: webserver
* Назначение: предоставлять web-клиентам доступ к жестко закодированным web-страницам
* Применение: webserver <appnum>
*----------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int f; //FileHandle
connection conn;
unsigned int i,len,bytesread;
int n;
char buff[BUFFSIZE], ctype[25], cmd[16], path[64], vers[16], ip_client[17];
char fname[_MAX_PATH]; //FileName
char* fcontent; //FileContent
if (argc != 2) {
(void) fprintf(stderr, "usage: %s <appnum>\n", argv[0]);
exit(1);
}
printf("\nWeb Server ...\n\n");
while(1) {
/* Ожидать поступления запросов на установление соединения через порт appnum */
conn = await_contact((appnum) atoi(argv[1]), ip_client);
if (conn < 0)
exit(1);
/* Прочитать и интерпретировать строку запроса*/
n = recvln(conn, buff, BUFFSIZE);
sscanf(buff, "%s %s %s", cmd, path, vers);
/* Пропустить все строки заголовка – выполнять чтение, пока не будет получена строка, состоящая только из символов \r\n */
while((n = recvln(conn, buff, BUFFSIZE)) > 0) {
if (n == 2 && buff[0] == '\r' && buff[1] == '\n')
break;
}
/* Выполнить проверку, не произошло ли непредвиденное получение признака конца файла */
if (n < 1) {
(void) send_eof(conn);
continue;
}
/* Выполнить проверку, не получен ли запрос такого типа, обработка которого не предусмотрена */
if (strcmp(cmd, "GET") || (strcmp(vers, "HTTP/1.0") &&
strcmp(vers, "HTTP/1.1"))) {
send_head(conn, 400, strlen(ERROR_400), NULL);
(void) send(conn, ERROR_400, strlen(ERROR_400),0);
(void) send_eof(conn);
continue;
}
/* интерпретация имени файла*/
for(i=0;i<strlen(path);i++)
fname[i]=path[i+1];
if(!strcmp(path, "/"))
strcpy(fname,"index.html");
printf("Client(ip=%s) request file %s.\n",ip_client,fname);
if ((f=_open(fname, _O_BINARY))==-1)
{
printf("Cannot open required file %s.\n",fname);
send_head(conn, 404, strlen(ERROR_404), NULL);
(void) send(conn, ERROR_404, strlen(ERROR_404),0);
(void) send_eof(conn);
continue;
}
len=_filelength(f); //Размер файла
if ((fcontent=malloc(len))==NULL)
{
printf("Insufficient memory available.\n");
(void) send_eof(conn);
exit(1);
}
/* Определение типа файла*/
if(strstr(fname,".gif")) strcpy(ctype,"image/gif");
else
if(strstr(fname,".jpg")) strcpy(ctype,"image/jpg");
else
if(strstr(fname,".png")) strcpy(ctype,"image/png");
else
if(strstr(fname,".mso")) strcpy(ctype,"image/mso");
else
if(strstr(fname,".wmz")) strcpy(ctype,"image/wmz");
else
if(strstr(fname,".zip")) strcpy(ctype,"application/zip");
else
if(strstr(fname,".exe")) strcpy(ctype,"application/octet-stream");
else
strcpy(ctype,"text/html");
// read file
if((bytesread = _read(f, fcontent, len))<=0)
printf("Problem reading file %s\n",fname);
else
printf("Read %u bytes from file %s\n", bytesread, fname);
_close(f);
/* Передать затребованную web - страницу */
send_head(conn, 200, len, ctype);
(void) send(conn, fcontent, len, 0);
(void) send_eof(conn);
free(fcontent);
}
return 0;
}
/*------------------------------------------------------------------------------------------* send_head – передает заголовок HTTP 1.0 с заданным кодом состояния
* и значением длины информационного наполнения
*------------------------------------------------------------------------------------------*/
void send_head(connection conn, int stat, int len, char* ctype)
{
char *statstr, buff[BUFFSIZE];
/* Преобразовать код состояния в строку */
switch(stat) {
case 200:
statstr = "OK";
break;
case 400:
statstr = "Bad Request";
break;
case 404:
statstr = "Not Found";
break;
default:
statstr = "Unknown";
break;
}
/*
* Передать запрос HTTP/1.0 со строками заголовка Server, Content-Length,
* и Content-Type.
*/
(void) sprintf(buff, "HTTP/1.0 %d %s\r\n", stat, statstr);
(void) send(conn, buff, strlen(buff), 0);
(void) sprintf(buff, "Server: %s\r\n", SERVER_NAME);
(void) send(conn, buff, strlen(buff), 0);
(void) sprintf(buff, "Content-Length: %d\r\n", len);
(void) send(conn, buff, strlen(buff), 0);
(void) sprintf(buff, "Content-Type: %s\r\n", ctype);
(void) send(conn, buff, strlen(buff), 0);
(void) sprintf(buff, "\r\n");
(void) send(conn, buff, strlen(buff), 0);
}
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.