[lwip-users] Re: Probem sending large files using LwIP (Kieran Mansley)
From:
Louis Filasky
Subject:
[lwip-users] Re: Probem sending large files using LwIP (Kieran Mansley)
Date:
Tue, 17 Jul 2007 17:55:27 +0200
On Sat, 2007-07-14 at 19:24 +0200, Louis Filasky wrote:
> First, we couldn t send more than around 8000 bytes of data. > This was fixed by changing the argument in the tcp_write > function by choosing > not to copy before sending the data.
> Can I just check that you're doing something to make sure the data you > send are preserved until you get the tcp_sent() callback? By specifying > not to copy, you're saying the data you pass to tcp_write() are static > until the callback is made to say the stack has finished with those > data. It's not just a magic switch to make things faster!
Hi everyone,
Thanks to your suggestion, I was able to improve my code but I determined what was wrong. In EDK, you are able to change some
values for lwIP using a file xiledk_opt.h. The thing if that if you look at that file in the EDK install directory where the lwIP sources lies,
it is empty but the lwipopt.h includes th e xiled_opt.h. Then I went in the compiled sources of the project and you can see that
this file is no longer empty and redefines suche variables as MEMORY_SIZE or SND_BUF.
Changing the MEMORY_SIZE, I was able to send larger files. I set it up to the maximum file size I could send so now when I ask the server
to change a large file, the client is at least receiving data and creating the file which it was not doing before that.
Following Kieran suggestion, I use now the argument 1 when I call tcp_write. However, now I am limited by the size of the send buffer.
Whatever the size I choose, if I try to send a file larger than the send buffer, it will only send the maximum send buffer size.
Now in my send_data() function, I handle when the data is bigger than the send buffer:
/* We cannot send more data than space available in the send buffer.*/ if(tcp_sndbuf(pcb) < (cs->left)) { len = tcp_sndbuf(pcb); } /* Otherwise, the length is equal to the size of the data to be sent */ else { len = cs->left; }
err = tcp_write(pcb, cs->data, len, 1);
/* Queue the data to be sent, if tcp_write does not send back ERR_OK, force the data transfer. */ if(ERR_OK==err) { cs->data += len; cs->left -= len; } else if(err==ERR_MEM) { tcp_output(pcb); }
/* If the data to be send is smaller than the send buffer size, then force the data transfer to speed it up. */ if(cs->left == 0) { tcp_output(pcb); } }
If I try to send a file of 50.000 bytes and let's say the sendbuffer max size is 40960, the left variable is set to be 9040.
But in my server_sent callback function, if left is > 0, it should call again send_data:
err_t server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { struct connection_state *cs; cs = arg; xil_printf("tets %d\r\n", cs->left); //Once the server has received ACK from client that data has been successfully transmitted, //check if there is still some more data to send and initiate transmission. if(cs->left >0) { send_data(pcb, cs); xil_printf("test2"); } return ERR_OK;
}
But when I send any data larger than the sendbuffer size, it never goes in the if condition and the xil_printf before the if condition is always
displaying 0.
Now, in my server_received callback function, i have the followings:
if(err == ERR_OK && p!=NULL) { //Inform TCP that received data is being handled: tcp_recved(pcb, p->tot_len); processCommand(p, pcb, cs); tcp_sent(pcb, server_sent); } else pbuf_free(p);
return ERR_OK;
With processCommand being a function which analyzes the command received from the client and send the corresponding data. So the last
line of the function is actually a call to send_data().
I must be doing something wrong, so if anyone has got a hint, thanks!
Antoine.
Besoin d'un e-mail ? Créez gratuitement un compte Windows Live Hotmail et bénéficiez de 2 Go de stockage ! Windows Live Hotmail