본문 바로가기

컴퓨터 공학 자료(학부)/Network

최소형 웹서버 만들기


과제로 교수님이 내주셨는데
상당히 유용하고 도움이 많이 되는 과제이다
이를 구현하기 위해선 당연히
웹서버와 웹 클라이언트가 주고받는 http 프로토콜을 이해해야하고
소켓 통신을 이해해야하고
추가로 파일크기를 줄이기 위해 각종 컴파일 옵션들을 알아야 한다.

기능

·          .html 또는 .html 확장 자를 가진 정적 웹 페이지를 브라우저에 전송한다

·          .gif, .png, .jgp, .jpeg 같은 그래픽 이미지를 브라우저에 전송한다.

·          .zip, .gz, .tar 등 압축 바이너리 파일과 아카이브를 브라우저에 전송한다.

·          다중 동시 접속을 처리한다.

·          http 프로토콜을 처리한다



사실 이번 과제의 모토는 최소형 웹서버 구현인데 시간과 노력의 대부분을 웹서버 기능 구현보다는 최소형에 투자하였다. 8:2의 비율로 어떻게 하면 코드 사이즈를 줄일까 하는데에 초점을 맞추었다. 우선 다중접속을 위한 처리방식으로는 멀티 프로세스, 멀티플렉싱, 멀티 쓰레드 등이 있는데 본 서버 프로그램에서는 간단한 멀티 쓰레드 방식을 이용하였다. 또한 데이터그램 단위로 패킷을 전송하는UDP 방식보단 데이터흐름 전송 방식인TCP 방식으로 구현 하는 것이 낫다고 판단하여 후자를 이용하여 데이터를 전송하고 웹 서버와 상용브라우저간 http 프로토콜을 처리하도록 하였다. 그 외에 이번 과제의 모토인 코드 최소형 웹 서버를 구현하기 위해 다음과 같은 절차를 거쳤다.

 

1.  IE, FireFox 등 상용 브라우저는 메타데이터 전송을 일부 생략해도 알아서 필요한 파일을 인식하여 처리해주므로  "HTTP/1.0 200 OK\r\n"

"Content-type:text/plain\r\n\r\n" 두가지 메타데이터만 전송하도록 했다.

2.  컴파일러를 다양하게 사용해보았는데, 테스트결과 컴파일러마다 실행코드 크기는 다음과 같다.

Dev++ 내장 컴파일러(24kb)

VS 2008 cl.exe(7kb)

Gcc 컴파일러(7.2kb)

Lcc 컴파일러(32kb)

 

파일 포맷 merging과 파일 alignment를 수행하지 않았을 때 gcc가 각종 옵션(-Os -s -finline-functions -floop-optimize )을 걸어주었을 때 사실 cl.exe(Vs 2008)보다 코드 크기가 작았지만 cl.exe gcc보다 옵션 주기가 편하고 전처리를 통해 링커를 다루기가 편하기 때문에 cl.exe 를 컴파일러로 이용 하였다.

 

3.  엔트리포인트 강제 지정을 통해 약2kb 정도 코드 사이즈를 줄여냈다.

C로 만들어진 Exe 프로그램은 프로그램 실행 시에 겉보기엔 main 함수가 명시적인 엔트리 포인트로 지정되어 실행되는 것처럼 보이지만, 실은 내부에 다른 함수가 먼저 수행되고 프로그램 초기화, 커맨드라인 처리 등을 거쳐 main 함수가 수행된다. 따라서 본 웹서버에서는 커맨드 라인 입력 부분을 없애서 main 함수 전 초기화 함수가 수행될 필요가 없도록 하였고  이를 건너뛰어 초기화 함수 수행에 필요한 메모리 2kb정도를 아끼고 바로 main 함수로 가도록 엔트리 포인트를 강제 지정하였다.  

4.  파일 정렬(alignment)와 합병(merging)을 통해 2kb 정도 코드 사이즈를 compact 했다.

C 코드를 컴파일, 빌드 후 나온 결과물은 PE 파일 포맷을 따르는 exe 파일인데, PE 파일 구조는 알려진 대로 코드 데이터를 .text, .data, .reloc 섹션 등으로 나누어 저장한다. 다시 말해 각 섹션에 저장된 데이터 뒤에 빈 공간이 생길 가능성이 매우 높다는 뜻이다. 따라서 각 섹션을 강제로 병합시킴으로 또 2kb 바이트 정도를 줄일 수 있었다.

 

5.  VC6 버전 cl.exe(컴파일러) 이용함으로써 닷넷 프레임워크 독립성 획득

사실 2008 컴파일러가 VC6 버전보다 성능이 우수한 건 사실이나 속된 말로 vc6 버전 컴파일러는 프로그래머의 느슨한 문법사용에관대한 경향이 있다. 따라서 vc6 컴파일러를 이용하여 많은 것을 얻을 수 있었는데 우선 닷넷 프레임워크 버전에 대해 독립성을 얻을 수 있었다. 2008이나 2005에서 컴파일해서 얻은 서버 프로그램 exe의 경우 비쥬얼스튜디오 2005 2008이 깔려있지 않은 시스템에서는 동작하지 않는다. 왜냐하면 윈도우에서 기본으로 제공하는 dll 외에 자체 닷넷 프레임워크 dll을 쓰레드 구동에 이용하기 때문이다. 하지만 VC6 컴파일러의 경우 기본적으로 윈도우 제공 dll만 사용하여 쓰레드를 호출 하기 때문에 비쥬얼스튜디오, 닷넷프레임워크가 깔려있지 않는 시스템에서도 독립적으로 동작한다.

 

6.  C의 기본 헤더인 stdio.h string c 기본 라이브러리 사용을 배제하고 win 32 api 라이브러리 이용. C의 기본 라이브러리의 fread, fopen, memset 등을 대체하는 win 32api CreateFile, ReadFile, ZeroMemory 등을 이용하여 c 기본 라이브러리 호출을 배제하였고, 이에 의해 소모되는 메모리 약 1kb 정도를 줄일 수 있었다.




서버 파일을 더블 클릭하여 실행하면 클라이언트 접속이 있을 때까지 무한루프(while(1)) 상태로 대기한다.  그리고 브라우저 주소 창에 ‘http://localhost:<9999>/<요청파일>’ 입력하여 서버로 접속한다. Ex) http://localhost:9999/index.html (포트주소는 직접 지정하였다)

        Command line 에서 직접 프로그램명.exe  포트번호를 임의로 입력 받아서 서버를 실행 시키는 방법도 있지만, 방법보다는 미리 포트를 설정해두고(9999) 더블클릭만 하면 실행되도록 하였다. 실제로 서버를 실행시키면 콘솔 창에 아무런 메시지가 뜨는데 코드 최소화를 위해 모든 화면 출력 메시지를 생략했기 때문이다.