Il 22/11/2017 17:07, address@hidden ha scritto:
Giuseppe Modugno wrote:
I'm trying to understand the mechanisms under
TCP_WRITE_FLAG_MORE, tcp_write() and tcp_output(). I'm using
raw API.
First of all, I couldn't understand if tcp_output() is useful
or not.
Why do you think all the world would call tcp_output() if it's not
useful?
You're right, maybe a better question would be: "what is the utility
of tcp_output()?".
Before sending my post, I checked the use of tcp_output() in lwip
apps and I found only httpd, lwiperf and mqtt use it.
I understood tcp_output() *really* outputs unsent data,
pushing all data to netif driver. Here it's not clear:
- if unacked data (data already sent but not yet
acknlowedged) is sent too;
No, it's not. Unacked data is only retransmitted for a 'rexmit'
event. To do that, it is moved back to 'unsent' and tcp_output()
is called.
- what happens if data in the output buffer is bigger than
what netif driver could accept in its sending function
Then it is not sent. :-)
TCP re-triggers tcp_output() if data is ACKed or new data is
received or in a timer, so eventually, more data is sent.
- (maybe a well written application checks tcp_sndbuf()
before writing output data, so this event never happens).
No, tcp_sndbuf() does not know anything about your netif driver.
For example:
tcp_write(...)
tcp_write(...)
tcp_write(...)
tcp_output()
Is tcp_output() really needed?
Yes, of course! If not, I would have deleted it already ;-)
It seems data are send even without calling tcp_output().
It is, but only at some time later (by tcp_tmr). This drops your
throughput, of course.
So it's better to call tcp_output() as soon as there aren't more
data available to send.
Another question is the correspondence between tcp_write()
calls and output TCP segments, IP packets and Ethernet frames.
Are three TCP segments, three IP packets and three Ethernet
frames generated? Does lwip try to compact output data in a
single TCP segment, IP packet and Ethernet frame?
Yes, data is appended, to unsent segments. However, it's not easy
to cite the rules here, as there are many optimizations in this
path. In the end, don't try to rely on something here!
Another question is about TCP_WRITE_FLAG_MORE flag.
I understood this flag should be set in all tcp_write() except
the last. However it seems it works with and without that flag
in sending data.
Of course it works, but pbuf allocation and tcp header flags
differ. If it doesn't make a difference for you, you can just set
the flag to what you want.
It should be nice to understand when this flag could be and not be
useful.
|