lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] tcp_sndbuf always returns 0


From: WU Rui-Qing
Subject: [lwip-users] tcp_sndbuf always returns 0
Date: Thu, 16 Jul 2009 23:39:14 +0800

Hi,

   I want to port httpd.c as a high-speed server, it reads data from a FIFO and 
send data to TCP client. After it works for a moment, it slows down. tcp_sndbuf 
always returns 0. Some parameters are listed in lwipopts.h .
   I am waiting for your advice ,thanks a lot!






/*************************************************************************/
struct ncu_demon_state {
  char *file;
  u16_t left;
  u8_t retries;
};


/*-------------------------------------------------------*/
int ncu_demon_input(char *buff,int len)
{
   int rc=0;
   hpi_input(buff, len);
   return rc;
}


/*-----------------------------------------------------------------------------------*/
static void
ncu_demon_conn_err(void *arg, err_t err)
{
  struct ncu_demon_state *hs;

  LWIP_UNUSED_ARG(err);

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

   /*
     We cannot send data before connection established
   */
  if(pcb->state < ESTABLISHED)
    return ;

  /*
     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;
  }
  if(len<=0)  /* len */
     return ;

  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;
  }
  else
  {
    PRINT("send_data: error %s len %d %d\n", lwip_strerr(err), len, 
tcp_sndbuf(pcb));
  }
}
/*-----------------------------------------------------------------------------------*/
static err_t
ncu_demon_poll(void *arg, struct tcp_pcb *pcb)
{
  struct ncu_demon_state *hs;
  HPI_FIFO_BLOCK *cur_item=NULL;

  hs = arg;

  /*  PRINT("Polll\n");*/
 // if (hs == NULL) {
 if ((hs == NULL) && (pcb->state == ESTABLISHED)) //patch for memory leak by 
wrq 2009-04-08
        {
    /*    PRINT("Null, close\n");*/
    tcp_abort(pcb);
    return ERR_ABRT;
  }
  else
  {
      if (hs->left<=0)// unused
      {
            cur_item=read_block_from_outfifo(POS_FIX);
            if((cur_item)&&(cur_item->len>0)) //
            {
                  if((*(cur_item->data)==APP_SYN_CODE)&&
                      (cur_item->len<0x10000))
                  {
                          hs->left=cur_item->len;
                          hs->file=(char*)(cur_item->data);
                        
                          ncu_demon_snd++;
                          add_demon_cache(hs->left,(u32_t)(hs->file));
                  }
                  cur_item->flag=0;
            }
          }
    ncu_demon_send_data(pcb, hs);
  }

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

  LWIP_UNUSED_ARG(len);

  hs = arg;

  hs->retries = 0;

  if (hs->left > 0)
  {
    ncu_demon_send_data(pcb, hs);
  }
  else
  {
    //close_conn(pcb, hs);// important ! ,after all data are sent  ,
  }

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
ncu_demon_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  int i;
  int pos=0;
  struct ncu_demon_state *hs;
  int len=0;
  char data[4096];
  u8_t  *ptr=NULL;
  struct pbuf *q;
//  HPI_FIFO_BLOCK *cur_item=NULL;

  memset(data,0,sizeof(data));

  hs = arg;

  if (err == ERR_OK && p != NULL)
  {
    /* Inform TCP that we have taken the data. */
    tcp_recved(pcb, p->tot_len);

    len=p->tot_len;
    if (len>0)
    {   
           //dump http request into linear-array from pub chain
           pos=0;
           len=p->tot_len;
           for(q = p; q != NULL; q = q->next)
           {
                   ptr = (u8_t *)q->payload;
               for(i = 0; i < q->len; i += 1)
               {
                 data[pos++] =*ptr++;
               }
            }
            // notify input data to HPI         
            ncu_demon_input(data, len);                 

     }
         // handle      
     /* PRINT("data %p len %ld\n", hs->file, hs->left);*/
     pbuf_free(p);

    }
    else
    {
      pbuf_free(p);
    }

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

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(err);

  tcp_setprio(pcb, TCP_PRIO_MIN);

  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = (struct ncu_demon_state *)mem_malloc(sizeof(struct ncu_demon_state));

  if (hs == NULL) {
    PRINT("ncu_demon_accept: mem_malloc fail\n");
    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, ncu_demon_recv);

  tcp_err(pcb, ncu_demon_conn_err);

  tcp_poll(pcb, ncu_demon_poll, 0);

  /* 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, ncu_demon_sent);

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
void
ncu_demon_init(void)
{
  struct tcp_pcb *pcb;
  err_t err;
  pcb = tcp_new();
  if(!pcb)
  {
    PRINT("ncu_demon_init: tcp_new fail\n");
    return ;
  }
  err=tcp_bind(pcb, IP_ADDR_ANY, DEMON_PORT);
  if(err != ERR_OK)
  {
     PRINT("ncu_demon_init: tcp_bind fail\n");
     return;
  }
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, ncu_demon_accept);

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

#endif //




        


                                
        WU Rui-Qing
address@hidden
          2009-07-16

Attachment: lwipopts.h
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]