yes ,when call tcp_close(),they go to FIN_WAIT1,
I reduce the TCP_FIN_WAIT_TIMEOUT and the TCP_MSL values, but my 100
tcp_pcb have been exhausted.
I find it from the mem states.
Can you look into my code and give me some advice.


> When I call tcp_close(),the program will send FIN,

At which point the connection will (or at least should) move from
ESTABLISHED to FIN_WAIT1.

> and then the
> receiver will reply FIN

At which point we'll go through FIN_WAIT2 to TIME_WAIT.

> But the tcp_pcb haven't been free after this operation.

It will have to wait to timeout from TIME_WAIT before it is freed.

However, you said in an earlier post that the connection was still in
the ESTABLISHED TCP state.  If that is the case I don't know what is
going on.

Kieran

/*------------------------------------------------------------*/
/*  Sample task of http                                                         
                  */
/*------------------------------------------------------------*/
#include    <stdio.h>
#include    <string.h>
#include    <ctype.h>
#include    <stdlib.h>
#include    "lwip/sys.h"
#include    "lwip/api.h"
#include    "lwip/httpd.h"

//by ming 2005-01 add counter & runtimer
u32_t runtime=0;
u32_t counter=0;
void httpd_init(void);
/*-----------------------------------------------------------------------------------*/
static void
conn_err(void *arg, err_t err)
{
  struct http_state *hs;

  hs = arg;
  mem_free(hs);
}
/*-----------------------------------------------------------------------------------*/
static void
close_conn(struct tcp_pcb *pcb, struct http_state *hs)
{
  tcp_arg(pcb, NULL);
  tcp_sent(pcb, NULL);
  tcp_recv(pcb, NULL);
  mem_free(hs);
  tcp_close(pcb);
}
/*-----------------------------------------------------------------------------------*/
static void
send_data(struct tcp_pcb *pcb, struct http_state *hs)
{
  err_t err;
  u16_t len;

  /* We cannot send more data than space available in the send
     buffer. */     
  if(tcp_sndbuf(pcb) < hs->left) {
    len = tcp_sndbuf(pcb);
  } else {
    len = hs->left;
  }

  do {
    err = tcp_write(pcb, hs->file, len, 0);
    if(err == ERR_MEM) {
      len /= 2;
    }
  } while(err == ERR_MEM && len > 1);  
  
  if(err == ERR_OK) {
    hs->file += len;
    hs->left -= len;
  }
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_poll(void *arg, struct tcp_pcb *pcb)
{
  struct http_state *hs;

  hs = arg;
  
  /*  printf("Polll\n");*/
  if(hs == NULL) {
    /*    printf("Null, close\n");*/
    tcp_abort(pcb);
    return ERR_ABRT;
  } else {
    ++hs->retries;
    if(hs->retries == 4) {
      tcp_abort(pcb);
      return ERR_ABRT;
    }
    send_data(pcb, hs);
  }

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct http_state *hs;

  hs = arg;

  hs->retries = 0;
  
  if(hs->left > 0) {    
    send_data(pcb, hs);
  } else {
    close_conn(pcb, hs);
  }

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  int i;
  char *data;
  struct http_state *hs;
  //by ming 2005.01
  u8_t hour,min,sec;
  u16_t day;
  

  hs = arg;

  if(err == ERR_OK && p != NULL) {

    /* Inform TCP that we have taken the data. */
    tcp_recved(pcb, p->tot_len);
    
    if(hs->file == NULL) {
      data = p->payload;
      
      if(*data =='G') {
                for(i = 0; i < 40; i++) {
                        if( ((char *)data + 4)[i] == ' ' || ((char *)data + 
4)[i] == '\r' || ((char *)data + 4)[i] == '\n') {
                                        ((char *)data + 4)[i] = 0;
                        }// if
                }//for
        
                // if it was GET dsp.jpg
                if ((*(data+5) =='d') && (*(data+6) =='s') && (*(data+7) 
=='p')) {
                        //hs->file = (char *)&jpeg;
                        //hs->left = sizeof(jpeg);
                }
                // if it was GET dsk.jpg (large one)
                else if ((*(data+5) =='d') && (*(data+6) =='s') && (*(data+7) 
=='k')) {
                        //hs->file = (char *)&large;
                        //hs->left = sizeof(large);
                }
                // GET other files
                else {
                        hs->file = (char *)&demo;
                        hs->left = sizeof(demo);
        /*
                        
//-----------------------------------------------------------------
                        //counter
                        counter ++;
                        sprintf(&demo[517],"%.6d",counter);
                        //runtime
                        runtime = OSTimeGet() / 80; ///100; //tmp by millin 
2005.01.23
                        sec = runtime % 60;
                        min = (runtime / 60) % 60;
                        hour = (runtime / 3600) % 24;
                        day = (runtime / 3600) / 24;
                        
sprintf(&demo[573],"%.3d:%.2d:%.2d:%.2d",day,hour,min,sec);
                        
//-----------------------------------------------------------------*/
                }       
                
                pbuf_free(p);
                send_data(pcb, hs);

                /* Tell TCP that we wish be to informed of data that has been
                successfully sent by a call to the http_sent() function. */
                tcp_sent(pcb, http_sent);
      
      } //if(*data =='G')
      
      else {
                        pbuf_free(p);
                        close_conn(pcb, hs);
      } //else if(*data =='G')
        
        } //if(hs->file == NULL) 
        
        else {
                pbuf_free(p);
    }
  }

  if(err == ERR_OK && p == NULL) {
    close_conn(pcb, hs);
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct http_state *hs;

  tcp_setprio(pcb, TCP_PRIO_MIN);
  
  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = mem_malloc(sizeof(struct http_state));

  if(hs == NULL) {
    return ERR_MEM;
  }
  
  /* Initialize the structure. */
  hs->file = NULL;
  hs->left = 0;
  hs->retries = 0;
  
  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the http_recv() function. */
  tcp_recv(pcb, http_recv);

  tcp_err(pcb, conn_err);
  
  tcp_poll(pcb, http_poll, 4);
  return ERR_OK;
}

/*-----------------------------------------------------------------------------------*/
void
httpd_init(void)
{
  struct tcp_pcb *pcb;

  //by ming 2005.1
  OSTimeSet((u32_t) 0x00000000);
  counter = (u32_t) 0x00000000;
    
  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 80);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, http_accept);

}
char sendBuf[129]={0};
static err_t
http_recv2(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  int i;
  char *data;
  struct http_state *hs;
  //by ming 2005.01
  u8_t hour,min,sec;
  u16_t day;
  struct pbuf *q=NULL;
  
        int len=0;
  hs = arg;

  if(err == ERR_OK && p != NULL) {

    /* Inform TCP that we have taken the data. */
    tcp_recved(pcb, p->tot_len);
        q=p;
        while(q)
        {
              data = q->payload;
              if(data) {
                        len = q->len;
                        while(len--)
                                {
                                sendBuf[len-1]=data[len-1];
                                }
                        sendBuf[len]=0;
                        hs->file = (char *)&sendBuf;
                        hs->left = q->len;
                        send_data(pcb, hs);
                //      break;
                        /* Tell TCP that we wish be to informed of data that 
has been
                        successfully sent by a call to the http_sent() 
function. */
                //      tcp_sent(pcb, http_sent);
                }
                  q=q->next;
        }
        pbuf_free(p);
  }

  if(err == ERR_OK && p == NULL) {
//    close_conn(pcb, hs);
  }
  return ERR_OK;
}
static err_t
http_accept2(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct http_state *hs;

  tcp_setprio(pcb, TCP_PRIO_MIN);
  
  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = mem_malloc(sizeof(struct http_state));

  if(hs == NULL) {
    return ERR_MEM;
  }
  
  /* Initialize the structure. */
  hs->file = NULL;
  hs->left = 0;
  hs->retries = 0;
  
  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the http_recv() function. */
  tcp_recv(pcb, http_recv2);

  tcp_err(pcb, conn_err);
  
  tcp_poll(pcb, http_poll, 4);
  return ERR_OK;
}

void
httpdecho_init(void)
{
  struct tcp_pcb *pcb;

  //by ming 2005.1
  OSTimeSet((u32_t) 0x00000000);
  counter = (u32_t) 0x00000000;
    
  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, 80);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, http_accept2);

}
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to