melinsoftware / meos

MeOS - A Much Easier Orienteering System
GNU Affero General Public License v3.0
48 stars 25 forks source link

SPORTident TCP port only accepts one client at a time #77

Open jsh-de opened 3 months ago

jsh-de commented 3 months ago

Hi Erik,

The TCP input option under the SPORTident tab is set up as a socket server, meaning it correctly [bind]s and [listen]s, however in the then following while-loop it only ever [accept]s one client socket connection at a time, receives ([recv]) data from that client socket until it is closed, only then a new server-side [accept] might happen for a next client socket connection.

This current implemetation means that only one TCP client is read from at any given time, possible additional clients will sit in the [accept] backlog for whatever [connect]-timeout they have (Winsock default: forever!), if they get lucky and the previously connected client disconnects, they will be accepted, and all potentially pending client data read at once.

My understanding is if we are setting up a TCP server, we should [accept] any number of incoming client connections, store the client socket handles into a collection, then [recv] on each of them in turn, remove clients from the collection when they signal a [shutdown] on their side, and then start the accept / recv cycle again. This way multiple TCP client data feeds would be possible.

Appropriate code in MeOS is in SportIdent.cpp, the while-loop begins in line 861.

Note that currently the server-side socket is [bind]ing/[listen]ing in blocking mode, for multiple accepts in parallel to work we will need to set the server socket as non-blocking using [ioctlsocket FIONBIO] and then handle (basically ignore) [accept] returning WSAEWOULDBLOCK.

Relevance: my personal radio project (jSh.Radio) might need multiple TCP feeds for multiple "Gateway" devices (on multiple frequencies and/or at multiple locations). Additionally, Oskar Bergs ROC project supports local network SIRAP output, at the moment only one ROC will be able to send punches, all other ROCs will send but never be received.

I have some working code for a TCP-SIRAP server that I can share privately if desired.

Thanks and best regards,

Simon

erikmelin commented 3 months ago

@jsh-de It has been like this always, and so for I have had no complaints from users. Clients sending punches are supposed to connect, send a punch, and then drop the connection. Repeat. Then it works with multiple senders.

But sure, I can add support for multiple connections, in a future version.