yankun 发表于 2012-7-21 10:13:47

有哪位大神用过uIP中的WEB Client?给讲解一下过程,看不懂呀

有哪位大神用过uIP中的WEB Client?给讲解一下过程,看不懂呀

下面是源码:
/**
* \addtogroup apps
* @{
*/

/**
* \defgroup webclient Web client
* @{
*
* This example shows a HTTP client that is able to download web pages
* and files from web servers. It requires a number of callback
* functions to be implemented by the module that utilizes the code:
* webclient_datahandler(), webclient_connected(),
* webclient_timedout(), webclient_aborted(), webclient_closed().
*/

/**
* \file
* Implementation of the HTTP client.
* \author Adam Dunkels <adam@dunkels.com>
*/

/*
* Copyright (c) 2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
*    copyright notice, this list of conditions and the following
*    disclaimer in the documentation and/or other materials provided
*    with the distribution.
* 3. The name of the author may not be used to endorse or promote
*    products derived from this software without specific prior
*    written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
* $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $
*
*/

#include "uip.h"
#include "uiplib.h"
#include "webclient.h"
#include "resolv.h"
#include "usart.h"

#include <string.h>

#define WEBCLIENT_TIMEOUT 100

#define WEBCLIENT_STATE_STATUSLINE 0
#define WEBCLIENT_STATE_HEADERS    1
#define WEBCLIENT_STATE_DATA       2
#define WEBCLIENT_STATE_CLOSE      3

#define HTTPFLAG_NONE   0
#define HTTPFLAG_OK   1
#define HTTPFLAG_MOVED2
#define HTTPFLAG_ERROR3


#define ISO_nl       0x0a
#define ISO_cr       0x0d
#define ISO_space    0x20


static struct webclient_state s;

/*-----------------------------------------------------------------------------------*/
char *
webclient_mimetype(void)
{
return s.mimetype;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_filename(void)
{
return s.file;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_hostname(void)
{
return s.host;
}
/*-----------------------------------------------------------------------------------*/
unsigned short
webclient_port(void)
{
return s.port;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_init(void)
{

}
/*-----------------------------------------------------------------------------------*/
static void
init_connection(void)
{
s.state = WEBCLIENT_STATE_STATUSLINE;

s.getrequestleft = sizeof(http_get) - 1 + 1 +
    sizeof(http_10) - 1 +
    sizeof(http_crnl) - 1 +
    sizeof(http_host) - 1 +
    sizeof(http_crnl) - 1 +
    strlen(http_user_agent_fields) +
    strlen(s.file) + strlen(s.host);
s.getrequestptr = 0;

s.httpheaderlineptr = 0;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_close(void)
{
s.state = WEBCLIENT_STATE_CLOSE;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
webclient_get(char *host, u16_t port, char *file)
{
struct uip_conn *conn;
uip_ipaddr_t *ipaddr;
static uip_ipaddr_t addr;

/* First check if the host is an IP address. */
ipaddr = &addr;
if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
    ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
   
    if(ipaddr == NULL) {
      return 0;
    }
}

conn = uip_connect(ipaddr, htons(port));

if(conn == NULL) {
    return 0;
}

s.port = port;
strncpy(s.file, file, sizeof(s.file));
strncpy(s.host, host, sizeof(s.host));

init_connection();
return 1;
}
/*-----------------------------------------------------------------------------------*/
static unsigned char *
copy_string(unsigned char *dest,
          const unsigned char *src, unsigned char len)
{
strncpy(dest, src, len);
return dest + len;
}
/*-----------------------------------------------------------------------------------*/
static void
senddata(void)
{
u16_t len;
char *getrequest;
char *cptr;

if(s.getrequestleft > 0) {
    cptr = getrequest = (char *)uip_appdata;

    cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
    cptr = copy_string(cptr, s.file, strlen(s.file));
    *cptr++ = ISO_space;
    cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);

    cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
   
    cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
    cptr = copy_string(cptr, s.host, strlen(s.host));
    cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);

    cptr = copy_string(cptr, http_user_agent_fields,
                     strlen(http_user_agent_fields));
   
    len = s.getrequestleft > uip_mss()?
      uip_mss():
      s.getrequestleft;
    uip_send(&(getrequest), len);
}
}
/*-----------------------------------------------------------------------------------*/
static void
acked(void)
{
u16_t len;

if(s.getrequestleft > 0) {
    len = s.getrequestleft > uip_mss()?
      uip_mss():
      s.getrequestleft;
    s.getrequestleft -= len;
    s.getrequestptr += len;
}
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_statusline(u16_t len)
{
char *cptr;

while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
    s.httpheaderline = *(char *)uip_appdata;
    ++((char *)uip_appdata);
    --len;
    if(s.httpheaderline == ISO_nl) {

      if((strncmp(s.httpheaderline, http_10,
                  sizeof(http_10) - 1) == 0) ||
       (strncmp(s.httpheaderline, http_11,
                  sizeof(http_11) - 1) == 0)) {
        cptr = &(s.httpheaderline);
        s.httpflag = HTTPFLAG_NONE;
        if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) {
          /* 200 OK */
          s.httpflag = HTTPFLAG_OK;
        } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
                  strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) {
          /* 301 Moved permanently or 302 Found. Location: header line
             will contain thw new location. */
          s.httpflag = HTTPFLAG_MOVED;
        } else {
          s.httpheaderline = 0;
        }
      } else {
        uip_abort();
        webclient_aborted();
        return 0;
      }
      
      /* We're done parsing the status line, so we reset the pointer
       and start parsing the HTTP headers.*/
      s.httpheaderlineptr = 0;
      s.state = WEBCLIENT_STATE_HEADERS;
      break;
    } else {
      ++s.httpheaderlineptr;
    }
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static char
casecmp(char *str1, const char *str2, char len)
{
static char c;

while(len > 0) {
    c = *str1;
    /* Force lower-case characters. */
    if(c & 0x40) {
      c |= 0x20;
    }
    if(*str2 != c) {
      return 1;
    }
    ++str1;
    ++str2;
    --len;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_headers(u16_t len)
{
char *cptr;
static unsigned char i;

while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
    s.httpheaderline = *(char *)uip_appdata;
    ++((char *)uip_appdata);
    --len;
    if(s.httpheaderline == ISO_nl) {
      /* We have an entire HTTP header line in s.httpheaderline, so
       we parse it. */
      if(s.httpheaderline == ISO_cr) {
        /* This was the last header line (i.e., and empty "\r\n"), so
           we are done with the headers and proceed with the actual
           data. */
        s.state = WEBCLIENT_STATE_DATA;
        return len;
      }

      s.httpheaderline = 0;
      /* Check for specific HTTP header fields. */
      if(casecmp(s.httpheaderline, http_content_type,
                     sizeof(http_content_type) - 1) == 0) {
        /* Found Content-type field. */
        cptr = strchr(s.httpheaderline, ';');
        if(cptr != NULL) {
          *cptr = 0;
        }
        strncpy(s.mimetype, s.httpheaderline +
                sizeof(http_content_type) - 1, sizeof(s.mimetype));
      } else if(casecmp(s.httpheaderline, http_location,
                          sizeof(http_location) - 1) == 0) {
        cptr = s.httpheaderline +
          sizeof(http_location) - 1;
       
        if(strncmp(cptr, http_http, 7) == 0) {
          cptr += 7;
          for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
          if(*cptr == 0 ||
             *cptr == '/' ||
             *cptr == ' ' ||
             *cptr == ':') {
              s.host = 0;
              break;
          }
          s.host = *cptr;
          ++cptr;
          }
        }
        strncpy(s.file, cptr, sizeof(s.file));
        /*        s.file = 0;*/
      }


      /* We're done parsing, so we reset the pointer and start the
       next line. */
      s.httpheaderlineptr = 0;
    } else {
      ++s.httpheaderlineptr;
    }
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static void
newdata(void)
{
u16_t len;

len = uip_datalen();

if(s.state == WEBCLIENT_STATE_STATUSLINE) {
    len = parse_statusline(len);
}

if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
    len = parse_headers(len);
}

if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
   s.httpflag != HTTPFLAG_MOVED) {
    webclient_datahandler((char *)uip_appdata, len);
}
}
/*-----------------------------------------------------------------------------------*/
void
webclient_appcall(void)
{
if(uip_connected()) {
    s.timer = 0;
    s.state = WEBCLIENT_STATE_STATUSLINE;
    senddata();
    webclient_connected();
    return;
}

if(s.state == WEBCLIENT_STATE_CLOSE) {
    webclient_closed();
    uip_abort();
    return;
}

if(uip_aborted()) {
    webclient_aborted();
}
if(uip_timedout()) {
    webclient_timedout();
}


if(uip_acked()) {
    s.timer = 0;
    acked();
}
if(uip_newdata()) {
    s.timer = 0;
    newdata();
}
if(uip_rexmit() ||
   uip_newdata() ||
   uip_acked()) {
    senddata();
} else if(uip_poll()) {
    ++s.timer;
    if(s.timer == WEBCLIENT_TIMEOUT) {
      webclient_timedout();
      uip_abort();
      return;
    }
      /*    senddata();*/
}

if(uip_closed()) {
    if(s.httpflag != HTTPFLAG_MOVED) {
      /* Send NULL data to signal EOF. */
      webclient_datahandler(NULL, 0);
    } else {
      if(resolv_lookup(s.host) == NULL) {
        resolv_query(s.host);
      }
      webclient_get(s.host, s.port, s.file);
    }
}
}

void webclient_datahandler(char *data, u16_t len)
{

}

void webclient_connected(void)
{
       
}


void webclient_timedout(void)
{

}

void webclient_aborted(void)
{

}

void webclient_closed(void)
{

}
/*-----------------------------------------------------------------------------------*/

/** @} */
/** @} */

yankun 发表于 2012-7-21 10:29:48

求大神指导
页: [1]
查看完整版本: 有哪位大神用过uIP中的WEB Client?给讲解一下过程,看不懂呀