A unique TCP endpoint address comprises an IP and a port number. When the client calls connect on it’s socket the OS assigns the next available ‘ephemeral’ port number to the local port field in the client’s socket structure. The interface IP and local port become the source address of the outgoing IP packets.
Clients on different hosts might coincidently use the same source port number but the source IPs are different and the endpoints remain uniquely addressed. Clients on the same host as the server will have the same source IP but source ports will be different and the endpoints remain uniquely addressed. This is a feature of the Sockets interface rather than Xojo.
A stack overflow is what happens when an application pushes too many stack frames onto it’s allocated stack space. Every time you call a procedure or function the state of the function that made the call is pushed onto the stack. When the function being called returns, the state of the function that made the call is popped off the stack.
On Windows 11 with an i7 processor I can easily connect to 400 sockets with each socket receiving a heartbeat message every 50ms. You can download the server project from here and the simulator project from here. Note that the server project saves a file to C:\Xojo\DeviceMonitor.txt which may need to be changed.
Also, you’ll notice that I’ve commented out App.heartbeatFile.Flush in the ProcessBuffer Method in the mySocketClass. When this is not commented out the simulator experiences 103 errors which point to socket’s not being created in a timely fashion.
I believe that all socket heartbeats are being written to the file, but I’ve only checked for first & last socket numbers.
im try your example and it works fine !
now i don’t understand what is the problem ?
may be that TCPsocket server side has problems if it is used in a project whith a GUI ?
I have a small server app which listens on two sockets and handles connection requests to each and then handles the traffic to the handoff sockets. It has a GUI and works fine using TCPSockets. However the traffic volume is very low.
I did some rough tests last night and was able to reliably crash a gui server application, by doing stuff I would normally avoid doing. The tests were made on Windows 10 with Xojo 2020r2.1 in debug.
//server
ServerSocket.MaximumSocketsConnected = 1010
ServerSocket.MinimumSocketsAvailable = 250
ServerSocket.Port = 8000
ServerSocket.Listen
//Client v1
var thisSocket as TCPSocket.
for i as integer = 1 to 1000
thisSocket = new TCPSocket
thisSocket.address = "localhost"
thisSocket.port = 8000
thisSocket.Connect
next
The server reliably crashed out after 300 to 500 connections. No exception or error message.
I was able to get a 1000 connections by throttling the client.
//Client v2
var thisSocket as TCPSocket
var start as UInt64, timeout as boolean
for i as integer = 1 to 1000
thisSocket = new TCPSocket
thisSocket.address = "localhost"
thisSocket.port = 8000
thisSocket.Connect
start = milliseconds
do
timeout = (milliseconds - start) > 2000
thisSocket.poll
loop until (thisSocket.IsConnected or timeout)
//keep a reference to connected sockets
if not timeout then
Window1.ActiveSockets.add(thisSocket)
end if
next
Function milliseconds() as UInt64
Return system.microseconds / 1000
End
What stands out is how long and how lumpy windows takes to establish those 1000 connections. I’d take a guess the stack-overflow is some reentrancy in the framework when it can’t keep up with demand for new connections. (A guess is all it is.)
if i not rem the code that you have insert in constructor, the exception is not raised
but, it could be anything but the big problem is that the error is not interceptable
anyway you can try on your system by commenting this part of your code in constructor
// Calling the overridden superclass constructor.
// Note that this may need modifications if there are multiple constructor choices.
// Possible constructor calls:
// Constructor() -- From TCPSocket
// Constructor() -- From SocketCore
Super.Constructor
'theProcessTimer = New myProcessTimer(me)
I believe you’ve reached the maximum number of timers your system can handle. By commenting out that line you won’t be processing the data being received from the sockets. The code would need to be refactored to process all received data from a single timer which would loop through the active sockets.