• Socket limits

    From Alan Adams@21:1/5 to All on Mon Apr 20 19:25:06 2020
    Hi

    I'm using all this free time to work on my slalom competition scoring
    system. It consists of a database server and a significant number of
    client applications, running anyt=where on a local network of RISC OS computers, mostly RPIs. The connections between them use TCP/IP.

    I'm stress testing the system at the moment by running the maximum number
    of clients. In addition to exposing several latent bugs, that only get hit
    very infrequently, it has shown up limits in a couple of pieces of
    software that aren't mine. A couple of my bugs showed up after a 2 hour
    run with the maximum number of clients on the network. The last 3 days
    have been spent finding more quickly reproducable ways to trigger them, so
    that I could find out what was happening. (It turned out all to be
    problems reading data around the wrap in a ring buffer.)

    I use SocketWatch to monitor incoming sockets and return poll reason 13 - pollword non-zero, in order to get the data read quickly. SocketWatch uses
    a bitmap to identify the sockets, and it's a 32-bit integer, meaning I can
    only monitor 32 sockets. This in turn limits the server to 28 clients, as
    4 bits are already in use. (The hardware timing system uses two to
    indicate that GPIO events have taken place, and there's a couple of others already tied up.)

    Each client has 3 sockets - one to broadcast a request for the server, one
    to listen to incoming data, and one to send data to the server. The server
    uses one broadcast, and one listen, plus one send socket per client.
    Running all this on one machine, as I have been doing in testing, can tie
    up 112 sockets. I also have Hermes and Messenger Pro running, plus
    shareFS, and those together use the first 10 sockets.

    It turns out Hermes and NewsHound both create a socket when they fetch,
    and delete it afterwards. This fails if socket number 95 is already in
    use, so I assume they are written with data allocated for handling 96
    sockets.

    I think I can reduce my socket usage by creating the broadcast sockets
    when needed and deleting them afterwards. That will need some testing of course. It's not just the initial connection that uses them - if a
    connection drops or times out, the system attempts to reconnect
    automatically.

    --
    Alan Adams, from Northamptonshire
    alan@adamshome.org.uk
    http://www.nckc.org.uk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paolo Fabio Zaino@21:1/5 to Alan Adams on Mon Apr 20 16:03:13 2020
    On Monday, April 20, 2020 at 7:28:48 PM UTC+1, Alan Adams wrote:
    Hi

    I'm using all this free time to work on my slalom competition scoring system. It consists of a database server and a significant number of
    client applications, running anyt=where on a local network of RISC OS computers, mostly RPIs. The connections between them use TCP/IP.

    I'm stress testing the system at the moment by running the maximum number
    of clients. In addition to exposing several latent bugs, that only get hit very infrequently, it has shown up limits in a couple of pieces of
    software that aren't mine. A couple of my bugs showed up after a 2 hour
    run with the maximum number of clients on the network. The last 3 days
    have been spent finding more quickly reproducable ways to trigger them, so that I could find out what was happening. (It turned out all to be
    problems reading data around the wrap in a ring buffer.)

    I use SocketWatch to monitor incoming sockets and return poll reason 13 - pollword non-zero, in order to get the data read quickly. SocketWatch uses
    a bitmap to identify the sockets, and it's a 32-bit integer, meaning I can only monitor 32 sockets. This in turn limits the server to 28 clients, as
    4 bits are already in use. (The hardware timing system uses two to
    indicate that GPIO events have taken place, and there's a couple of others already tied up.)

    Each client has 3 sockets - one to broadcast a request for the server, one to listen to incoming data, and one to send data to the server. The server uses one broadcast, and one listen, plus one send socket per client.
    Running all this on one machine, as I have been doing in testing, can tie
    up 112 sockets. I also have Hermes and Messenger Pro running, plus
    shareFS, and those together use the first 10 sockets.

    It turns out Hermes and NewsHound both create a socket when they fetch,
    and delete it afterwards. This fails if socket number 95 is already in
    use, so I assume they are written with data allocated for handling 96 sockets.

    I think I can reduce my socket usage by creating the broadcast sockets
    when needed and deleting them afterwards. That will need some testing of course. It's not just the initial connection that uses them - if a connection drops or times out, the system attempts to reconnect automatically.

    --
    Alan Adams, from Northamptonshire
    alan@adamshome.org.uk
    http://www.nckc.org.uk/

    Hi Allan,
    I can confirm that the maximum number of concurrent sockets at the moment available on RISC OS (any release) is 96.

    I tested this not too long ago with a simple C code that opens them on a local machine until the OS refuses to open more and the number turn out to be 96.

    After some investigation I have found this number is hardcoded in the OS Kernel source and it's so because of certain limitations related to the maximum number of files that can be opened together and how they are represented in the kernel (max number
    should be 256).

    The specific define should be SOCKTABSIZE (if i remember well). You can also measure what's available calling SWI Socket_Getsize.

    Basically on RISC OS sockets are in a distinct number space to file handles. Old programs may assume that file handles is an 8bit value (hence the 256) and so the limitation inherited by SOCKTABSIZE.

    So I'm afraid to make it to work you'll have to stick to probably max 94/95 sockets and if you want to use all 96 make sure nothing else is running on your RPi (not even OmniClient etc.)

    My 0.5c here, hope this helps,
    - Paolo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From druck@21:1/5 to Alan Adams on Tue Apr 21 00:59:44 2020
    On 20/04/2020 19:25, Alan Adams wrote:
    Each client has 3 sockets - one to broadcast a request for the server, one
    to listen to incoming data, and one to send data to the server. The server uses one broadcast, and one listen, plus one send socket per client.

    [Snip]

    Why do you need a send and receive socket? A single TCP socket can do
    both, you can even send out of band data to implement asynchronous notifications.

    I think I can reduce my socket usage by creating the broadcast sockets
    when needed and deleting them afterwards. That will need some testing of course. It's not just the initial connection that uses them - if a
    connection drops or times out, the system attempts to reconnect automatically.

    The clients broadcast socket can be created only when needed. Once
    you've sent a broadcast to identify the server, you should be able to
    reconnect to the same address after that.

    If you really need more clients, consider switching to UDP rather than
    TCP, as the sever can receive data from any number of clients on a
    single socket. You can chuck around far more data with UDP, but you have
    to take care of the integrity yourself.

    ---druck

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Adams@21:1/5 to druck on Tue Apr 21 15:39:45 2020
    In message <r7ld1j$fn3$1@dont-email.me>
    druck <news@druck.org.uk> wrote:

    On 20/04/2020 19:25, Alan Adams wrote:
    Each client has 3 sockets - one to broadcast a request for the server, one >> to listen to incoming data, and one to send data to the server. The server >> uses one broadcast, and one listen, plus one send socket per client.

    [Snip]

    Why do you need a send and receive socket? A single TCP socket can do
    both, you can even send out of band data to implement asynchronous notifications.

    Thanks for the comments. It's helped me clarify what actually happens.

    I've just trawled my way through the part of the code I wrote about ten
    years ago to handle connections.

    The listen socket listens for broadcast data. Not all of the applications
    need it, so there's one easy saving I can make.

    It's used for those applications where there must not be two copies
    running anywhere across the network. When one of those starts up it
    broadcasts a message effectively sayinf "are you there". Any pre-existing
    copy will reply. If the new copy wants to take over, it sends a "quit"
    message to the earlier copy, which shuts down. This allows control to be
    passed to a different computer for example.
    If it doesn't want to take over, it simply quits.

    I think I can reduce my socket usage by creating the broadcast sockets
    when needed and deleting them afterwards. That will need some testing of
    course. It's not just the initial connection that uses them - if a
    connection drops or times out, the system attempts to reconnect
    automatically.

    The clients broadcast socket can be created only when needed. Once
    you've sent a broadcast to identify the server, you should be able to reconnect to the same address after that.

    I think it will be fairly easy to create the broadcast socket as needed. I
    just need to check how easy it is to delete it cleanly after use.
    Alternatively I think I would need to record the server address and
    listen-port number to send the announcement that starts the reconnection.

    I'm now at a good point to look at these changes, as I've eliminated a long-standing bug that, at apparently random times, caused a disconnection followed by an inability to reconnect. It came down to the difference
    betweeen IF K%<0 and IF K%<=0.

    If you really need more clients, consider switching to UDP rather than
    TCP, as the sever can receive data from any number of clients on a
    single socket. You can chuck around far more data with UDP, but you have
    to take care of the integrity yourself.

    I've had another look at socketwatch, and I don't think I need a separate
    bit in the mask for each client. That seems to be used to allow the poll
    return to identify quickly which socket needs servicing. I'm scanning them
    all, so it shouldn't be needed.

    In normal use, I expect to need somewhere just over 20 clients across the network at a time. The socketwatch limitation I thought existed, would
    have made that a bit marginal.

    The socket limit of 96 would only apply in the unusual case of running all
    the clients on one computer. This would only occur during testing.


    ---druck


    --
    Alan Adams, from Northamptonshire
    alan@adamshome.org.uk
    http://www.nckc.org.uk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Adams@21:1/5 to Alan Adams on Wed Apr 22 12:59:55 2020
    In message <6ea3b76458.Alan.Adams@ArmX6.adamshome.org.uk>
    Alan Adams <alan@adamshome.org.uk> wrote:

    In message <r7ld1j$fn3$1@dont-email.me>
    druck <news@druck.org.uk> wrote:

    On 20/04/2020 19:25, Alan Adams wrote:
    Each client has 3 sockets - one to broadcast a request for the server, one >>> to listen to incoming data, and one to send data to the server. The server >>> uses one broadcast, and one listen, plus one send socket per client.

    <SNIP>

    I've now eliminated the unnecessary listen sockets.

    I think I can reduce my socket usage by creating the broadcast sockets
    when needed and deleting them afterwards. That will need some testing of >>> course. It's not just the initial connection that uses them - if a
    connection drops or times out, the system attempts to reconnect
    automatically.

    The clients broadcast socket can be created only when needed. Once
    you've sent a broadcast to identify the server, you should be able to
    reconnect to the same address after that.

    I've tried deferering the creation of the broadcast socket until it's
    needed, and i can't get it to work. Odd, because I'm using the same code,
    just called at a different place.

    I've tried running it on a different computer from the server and I can
    see packets going through the switch, but the server doesn't record
    anything as received.

    The sender is saying the port and socket are the same as in the working version, so I don't quite know what to look for next.

    I guess my next step will be Wiresalmon and see what the packets actually contain.

    ---druck




    --
    Alan Adams, from Northamptonshire
    alan@adamshome.org.uk
    http://www.nckc.org.uk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)