ServerSocket problems

I’m having problems receiving data from 400/500 devices that always transmit by calling the same IP and same communication port

I used the serverSocket as per the xojo example, but after the serverSocket has instantiated 200 TCPSockets, it continues to instantiate others but it seems that the new TCPSockets no longer receive data.
Is there a limit to the number of instantiable TCPSockets?
Are there any guidelines on how to correctly manage a similar scenario?

i think one tcpsocket that is set to listen mode act as web server where clients connect on the single port but the transfer is done via other ports, thats why port 80 and 443 always free for a connect request at a web server.

the connection can be permanent to send and receive
or you open send close

the processing of incomming data should be fast or in a thread

but if I need to have continuous communication and identify that the devices are online, what you describe is not the best

what i mean is you can have permanent connections like a drinking straw each and for all.
so 500 clients would block 500 ports.

or you send frequently a hello which connect and close for each client.

Do you mean that all 500 devices want to connect to one port number? Or that each device has its own port number to contact? Sounds like the former. When it gets a connection request, the listener socket takes a socket from its pool and passes the connection request to that. This is all handled automatically, what you observe is a Connected event for your working sockets. The new port number is not something you need to know about.

Have you set MaximumSocketsConnected ?

Once the socket is running it should not need to be disconnected. I do all my handling of the data in threads.

the devices that call the service are embedded products and I cannot intervene on their method of operation

all the devices call the same port, in fact the socketServer instantiates tcpSocket as there are requests, then the tcpSocket establishes communication and stores the data which will then be processed by 40 threads, the problem is that after about 200 instantiated tcpSockets, the new devices try to communicate but the new tcpSockets do not respond (once the 200 instantiated tcpSockets have been exceeded)

Don’t do that. The maximum number of sockets on a machine for all running services is 65535. The first 1024 are reserved by processes that are running as root and include ssh (22) http (80) https (443) and many other system services.

The other reason is that you’re telling the system that your app can handle that many being connected at the same time. A sensible number if you’re doing very fast processing is probably 1000.

yes I know the thing,

the concept is that I have also tried with such high values ​​even if the maximum number of instantiated tcpSockets never exceeds 3/4000 and after a day of work in which many connections fall for obvious reasons and are then recreated .
the only method I have found so far to solve is that after n. connections, I close everything and start from scratch, but the risk of losing data is high

The other reason is that you’re telling the system that your app can handle that many being connected at the same time. A sensible number if you’re doing very fast processing is probably 1000.

only 1000 ?

Furthermore, the app encounters some tcpSocket errors that cannot be intercepted and I wouldn’t want these to cause problems for the application and its connections

Don’t do that. The maximum number of sockets on a machine for all running services is 65535. The first 1024 are reserved by processes that are running as root and include ssh (22) http (80) https (443) and many other system services.

one precisation

ports that the SO uses for his internal services ares not the same object of sockets

you mean you have one TCPSocket in a window or class which listen,
and Xojo instantiated internally a new one after a connection was established?
and your app is always responsive after xxx clients are connected that a connect event can occur?

yes, the serverSocket object listens on a specific port, for each remote request it instantiates a new TCPSocket which will then communicate on that port with the device that started the communication all along (this is the job of the serverSocket… as if it were a reverse proxy server)

The maximum number of ports is 65535, but that is not the maximum number of sockets or connections. Unique ports are needed for listening, and for outgoing connections. Established connections do not need unique ports. An operating system can keep track of unique connections as long as the combination of “protocol + local address + local port + remote address + remote port” is unique. When a server socket listening on a specific port hands off a connection to a new socket, it can (and should) use the same local port for that connection. (I hope that is what Xojo is doing)

2 Likes

ok I did this test

I created an app server that listens on a specific port

I created a client app that with a for next loop tries to instantiate 1000 tcpSockets that try to connect to the server app and then begin to transmit data continuously through a timer

I run the two apps on the same PC (so server and client have the same IP)

  1. first of all, of the 1000 tcpSocket clients that I try to connect, only just under 500 connect, the others do not connect

  2. when all client sockets start transmitting data to the server app (via a timer),
    at a certain point the server app goes into error (exception on the dataavailable stack), an error not intercepted by the error handler of the same tcpsocket of the server, if I go to see the type of error communicated in the debugger there is no type of error or description, in practice it seems that the error cannot be intercepted, which will then cause an unmanageable problem in the app

debugger not show king of error and description

1 Like

Please share this example Server and Client xojo project via cloud.

all of this on issue #76141

1 Like

It says that it is a stack overflow exception.

1 Like

FWIW, Xojo Web uses a ServerSocket and doesn’t run into the types of issues that you are describing.

When I said 1000, I was talking about MaximumSocketsConnected, that is, the maximum that are connected simultaneously. You need to make sure that you’re giving the app itself time to process the incoming data. If you don’t, you’re just going to cause problems for yourself down the line.

One thing that almost everyone gets wrong when first using sockets of any kind is the rule about not processing data right in the DataAvailable events. The reason for this is that while socket events always fire on the main thread, they can fire when other code is already running (reentrancy). What you need to do is only use DataAvailable to add the incoming data to a buffer and then use something like Timer.CallLater to call a method that processes the data (assuming there isn’t already a call waiting to happen). I like to use a string array for the buffer because the code in DataAvailable can be just two or three lines long. Then you guard the processing method with a Boolean property or a CriticalSection to make sure you aren’t processing the same data twice.

Also, don’t assume that you’re getting whole streams of data in the same event. If the sent data exceeds the size of the buffer before DataAvailable fires, you’ll only get part of it at a time.

2 Likes

ok and this is first problem, then error manager of the class tcpsocket does not intercept the error
and this error will be an unandled app error

See my note about DataAvailable. That will help.