Технология клиент-сервер. Web

Страницы работы

Содержание работы

МО и НРФ

НГТУ

Кафедра  программных систем и баз данных

Лабораторная работа № 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);

}

Информация о работе