[Libwebsockets] Max # of bytes in 'buf' in lws_write command

Jon jon at mobilefs.com
Mon Apr 20 20:49:32 CEST 2015

Thanks Andy. Would you have any additional insight as to how the Windows Kernel might this (vs. say Linux)?

-----Original Message-----
From: Andy Green [mailto:extracats at googlemail.com] On Behalf Of Andy Green
Sent: Sunday, April 19, 2015 4:59 PM
To: Jon; libwebsockets at ml.libwebsockets.org
Subject: Re: [Libwebsockets] Max # of bytes in 'buf' in lws_write command

On 20 April 2015 00:47:10 GMT+09:00, Jon <jon at mobilefs.com> wrote:
>Hi Andy,

First I'm sorry but the mailing list delivery goes by gmail, and for the last week or so they have reduced the daily email quota to the point it can't send to the list.  I'll be moving to a static ip and send email directly hopefully today.

>Assuming enough buffer space has been allocated, is there a limit to 
>the # of bytes that the 'buf' parameter in libwebsocket_write function 
>can transport?

Depends on what you are asking... websockets supports endless amounts of data streamed on a websocket connection.  So at the highest level, no, there's no limit if you use the websocket fragment support (see how the fraggle test app does it).

For nonblocking sockets, which lws uses to allow us to multitask efficiently without threads, there's a basic problem though: by POLLOUT the kernel will signal to us that it will accept a new write on the connection, but there's no way to discover how much data the write action will accept to buffer in kernelspace without doing the write and seeing how much it took.

Basically the kernel dynamically decides per-connection by looking at how much data is backed up in kernelspace already on that connection and the overall memory pressure.  On Linux there seems to be a threshold around one or two MTU that it will always accept, otherwise it's dynamic.

Because of this unpredictable gap between knowing you can write 'something' but no information about how much, lws takes responsibility internally now to copy into a per-connection buffer the remaining unsent data and prioritizes draining that buffer before letting the user code send anything new.

So to the extent you can cope with a malloc'd buffer overhead, and blocking the websocket link for control packets, you can write something huge, in a nonblocking way, with one lws write.

But in the case the kernel is restricting what it accepts each time, that is not speeding you up, with the malloc'd buffer copy it's slowing you down.

The most efficient way overall is pick a chunk size that is usually or always accepted whole by the kernel (eg, 1500 or 4096), and each time it says the connection is writeable, loop stuffing the connection with these until it reports it is choked (see the test server).  The kernel will coalesce these into efficient send packets at the network device.  If you have huge data to send, also look at making use of the ws fragment stuff.


>Libwebsockets mailing list
>Libwebsockets at ml.libwebsockets.org

More information about the Libwebsockets mailing list