[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lwip-users] Retransmit too quick?
From: |
Xun Chen |
Subject: |
Re: [lwip-users] Retransmit too quick? |
Date: |
Mon, 06 Jul 2015 15:29:19 -0400 |
User-agent: |
Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 |
Hi, Sergio,
Thank you for your time!
I am not calling any raw api from interrupts and I don't use RTOS.
I include the pseudo codes below. (Note: In my codes, only one TCP connection
is allowed)
A) The following codes works, but I still get the (too quick) retransmit
problem after long run, making it hard to figure out
B) Another frustrating observation from my project
1) If I call sys_check_timeouts() without any delay, the throughput rate is
very low
2) If I call sys_check_timeouts() with 1ms delay right after it, the throughput
rate is high
3) If I call sys_check_timeouts() every 250ms plus the 1ms delay, the
throughput rate is the highest
Could you give me some pointer on where to look to solve the retransmit problem
and maybe some suggestion on how I should use raw APIs? I used FreeRTOS and
higher level lwip APIs several years ago and never had any issue like this.
Thanks a lot!
Chen
---------------------------
main()
{
...
gConnection=0;
...
lwIPInit();
..
tcp_pcb = tcp_new();
tcp_bind();
tcp_pcb = tcp_listen(tcp_pcb);
tcp_accept(tcp_pcb, echo_accept);
..
while(1){
...
if (gConnection){
if (tcp_sndbuf(active_tcp_pcb)>0){
if (tcp_write(active_tcp_pcb, ...,
TCP_WRITE_FLAG_COPY)==ERR_OK){
tcp_output(active_tcp_pcb));
}
}
}
if (250msElapsed()) //With this and Delay1ms, the performance is the
best
sys_check_timeouts();
Delay1ms();//Without this and(250msElapsed()), the performance is
horrible
}
err_t echo_accept(void *arg, struct tcp_pcb *pcb, err_t err){
if (gConnection==0){
active_tcp_pcb=pcb;
gConnection=1;
...
tcp_recv(pcb, echo_recv);
tcp_err(pcb, err_handler);
tcp_nagle_enable(pcb);
return ERR_OK;
}
return ERR_RST; //Allow only one connection
}
err_t echo_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){
if (err == ERR_OK && p != NULL) {
.... //Process the incoming data
tcp_recved(pcb, p->tot_len);
}
pbuf_free(p);
if (err == ERR_OK && p == NULL) {
close_conn(pcb);
}
return ERR_OK;
}
void err_handler(void * arg, err_t err){
close_conn(active_tcp_pcb);
}
void close_conn(struct tcp_pcb *pcb){
....
tcp_close(pcb);
gConnection=0;
}
---------------------------
If you are using the raw api and no RTOS, then your port should (must)
be calling the lwIP timers function and you don't have to do anything
with timers
(that is what I meant by "a broken timer implementation").
Your main should be something like
while(1){
sys_check_timeouts();
...
}
and you have to make sure it loops often (as it should).
You call the raw api functions only from the main loop, no calls on
interrupts. Do you ?
Re: [lwip-users] Retransmit too quick?, Xun Chen, 2015/07/06
Re: [lwip-users] Retransmit too quick?,
Xun Chen <=
Re: [lwip-users] Retransmit too quick?, Xun Chen, 2015/07/07
Re: [lwip-users] Retransmit too quick?, Xun Chen, 2015/07/08
Re: [lwip-users] Retransmit too quick?, Xun Chen, 2015/07/10
Re: [lwip-users] Retransmit too quick?, Xun Chen, 2015/07/13