[Top][All Lists]
[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
lwipopts.h
Description: Binary data
- [lwip-users] tcp_sndbuf always returns 0,
WU Rui-Qing <=