본문 바로가기

[INTERFACE]/WIZNET_EVM

[W5100 EVM]웹서버 예제

[W5100 EVM]웹서버 예제

 

 웹서버는 웹 페이지가 들어 있는 파일을 사용자들에게 제공하는 시스템으로 HTTP프로토콜으로 웹페이지및 응답을 송수신 할 수 있다.

임베디드 웹서버 펌웨어 소스


HTTP 프로토콜의 동작

HTTP 프로토콜은 요구/응답(Request/Response) 방식을 이용하여 동작하고 있다. , 원하는 프로토콜 기능(:GET, HEAD, POST)에 대해 서비스 요구를 하면 데이터 송수신을 위한 TCP 연결이 만들어지고, 서버가 응답을 보내어 데이터 전송을 끝내면 자동적으로 연결이 끊어지게 되는 것이다. 클라이언트가 서버와 TCP 연결을 만들고, 요구 method, URI, 프로토콜 버전, MIME의 형태로 표시되는 클라이언트 지정 사항들, 클라이언트 정보, 때로는 서버에게 전달할 내용 데이터까지 포함하는 요구 메시지의 형태로 서버에게 보낸다. 이에 대해 서버는 상태 정보를 보내는데, 프로토콜 버전, 성공 또는 오류코드 번호, 그리고 MIME의 형태로 표시되는 서버 정보를 포함하고, 엔터티의 메타정보, 전달할 내용 데이터 등을 포함하는 응답 메시지를 클라이언트에게 보낸다.

 

Request

HTTP Request 형식은 아주 간단하다. 첫 번째 줄 처음에 서버의 어떤 기능을 이용하려는지 지정을 하며 이것이 method이다. 가장 일반적으로 쓰이고 있는 것이 브라우저가 서버에게 문서를 보내달라고 요청하는  GET 이다.

그 다음에는 파일 이름과 위치하는 디렉토리 이름 등이 들어가는 MIME형식으로 표현되는 일련의 지정 사항들을 덧붙일 수가 있는데, 예를 들어 브라우저의 종류 같은 것이다. 아래와 같은 예를 볼 수 있으며, Request chain 이란 아래와 같이 여러 헤더로 구성되어 있는 요구 메시지를 일컫는 말이다.

GET /index.html HTTP/1.0

User-Agent: Netscape 1.2

 

 

Response

HTTP에서의 응답 형식도 아주 간단하게 구성되어 있다. 서버에서 쓰이고 있는 프로토콜 버전, Request에 대한 실행 결과 코드 및 설명문이 있으며, 전달해줄 데이터의 형식, 데이터 길이 등과 같은 추가적인 정보가 MIME 형식으로 표현되어 있다. 이어서 마지막에 헤더 정보의 끝을 나타내는 빈줄이 들어가고, 뒤이어 실제 데이터가 전달된다. 데이터 전달이 끝나면 서버는 연결을 끊는다.

Response chain 이란 여러 가지 헤더로 구성되어 있는 응답 메시지를 일컫는 말이며, 아래와 같은 예를 볼 수 있다.

Response Example

HTTP/1.0 200 OK 

 

 

예제

[5100 EVM]보드에 접속하면 아래와 같은 웹페이지를 볼 수 있다.

 

 예제소스 파일 구조

 

 

ROM File Maker : Webpage를 ROM File로 만들어 주는 유틸리티


 

 HTTP 프로토콜 처리 함수

void proc_http(SOCKET s, u_char * buf, int length)

{

             prog_char * content;

             char* name;

             char * param;

             u_int file_len;

             u_int send_len;

 

             unsigned char rxdata_buf[RX_MAX_BUF_SIZE];        

             unsigned char txdata_buf[TX_MAX_BUF_SIZE];         

            

             http_response = (u_char*)txdata_buf;                        // buffer for response header

             http_request = (st_http_request*)rxdata_buf;            // struct of http request

                                       

 

             // After analyze request, convert into http_request

             parse_http_request(http_request, buf);       

             //method Analyze

             switch (http_request->METHOD)                                          

             {

             case METHOD_ERR :                                                             

                           send(s, (u_char *)ERROR_REQUEST_PAGE, strlen(ERROR_HTML_PAGE));

                           break;

                          

             case METHOD_HEAD:

             case METHOD_GET:

             case METHOD_POST:

                           name = get_http_uri_name(http_request->URI);

 

                           // If URI is "/", respond by index.htm

                           if (!strcmp(name, "/")) strcpy(name,"index.html");

                          

                           //Check file type (HTML, TEXT, GIF, JPEG are included)

                           find_http_uri_type(&http_request->TYPE, name);     

                                       

                           //Search the specified file in stored binaray html image

                           if (!search_file(name, &content, &file_len))

                           {

                                        send(s, (u_char *)ERROR_HTML_PAGE, strlen(ERROR_HTML_PAGE));       

                           }

                           else

                           {

                                        make_http_response_head(http_response, http_request->TYPE, (u_long)file_len);                          

                                        send(s, http_response, strlen(http_response));

 

                                        while (file_len)

                                        {

                                                     if (file_len >= TX_MAX_BUF_SIZE-1)

                                                                  send_len = TX_MAX_BUF_SIZE-1;

                                                     else       send_len = file_len;

                                                     memcpy_P(http_response, content, send_len);

                                                     *(http_response+send_len+1) = 0;

                                                    

                                                     // Replace htmls' system environment value to real value

                                                     if(http_request->TYPE==PTYPE_HTML)

                                                     send_len = replace_sys_env_value(http_response,send_len);

                                                     send(s, http_response, send_len);

                                                     content += send_len;

                                                     file_len -= send_len;

                                        }

        }

                           break;

             default :

                           break;

             }

}

 


반응형