ServerSocket does not release TCPSocket

I want to receive the NOTIFY messages (from a network player sending the changes via HTTP NOTIFY messages, the content is XML)
Via a server socket.
There is a message from the network player every second, and 10 new EventListener sockets are generated every 10 seconds.
The messages are received correctly. The problem is now that the program needs more and more CPU.
For example, After 200 seconds the program in debugging stops you can see that 201 sockets are present!
1 EventServer and 200 EventListener.
Why are the event lists not released?

EventServer Subclass from ServerSocket
EventListener Subclass from TCPSocket

AddSocket in EventServer
mCurrentSocket = mCurrentSocket + 1
Dim ret As EventListener = New EventListener(mCurrentSocket)
Return ret

DataAvailable in EventListener
Dim buffer As String = ReadAll(Encodings.UTF8)
lastBuffer = lastBuffer + buffer.ToText
If mPosBeginBody = 0 Then
  mPosBeginBody = ParseHeader
End If

Dim contentLength As Integer
If mHeader.HasKey("CONTENT-LENGTH") Then
  contentLength = Integer.Parse(mHeader.Value("CONTENT-LENGTH"))
  Dim bodyLenght As Integer = LenB(lastBuffer) - mPosBeginBody
  If contentLength = bodyLenght Then
    CloseDataReceived
  End If
End If

In CloseDataReceived, the data is evaluated and

Self.Write "HTTP/1.1 200 OK" + Chr(13) + Chr(10) + Chr(13) + Chr(10)
Self.Flush
Self.Close

executed

Sockets take time to expire and then close
Usually about 2 minutes (really depends on the TCP timeout but I think thats normally 2 minutes)
I would suggest creating a waiting pool that gets created once, at app startup, and just recycle them while things are going on

  1. this will prevent you from running out of available sockets
  2. they don’t need to be created each time a request comes in

Otherwise you are at the mercy of the system and the sockets waiting around until the OS closes them from inactivity

Good idea. But how will that work. AddSocket is called after 10 Request and generates 10 new sockets?
Can you explain your idea to me more precisely. It can also be with pseudocode. Thank you

When AddSocket is FIRST called you generate 20 or so
Keep references to them in an array
Return item 0
Next time addsocket is called return item 1 (dont create a new one)
etc
Now its possible you get to a point where all 20 are busy (something you’ll need to track) and you actually do need to generate more
And if that is the case you add 20 more to the array and return the first not busy one
And then each time add socket is called you hunt for a not busy one and return that first before adding any more
If requests are coming in that fast few will ever time out and die

Just out of curiosity… does the Error event fire in those TCPSockets with an ErrorCode or 22 or 102?

The reason I ask is that we use the ServerSocket class in the web framework and I know that the sockets get released there.

Thanks. But What is the criterion for BUSY.
I see in the PortMonitor that all 20 sockets listen… (I have sent 20 notify request)

No ErrorCode.

Whoa, wait. If you’re not getting any error code, the client isn’t disconnecting when it’s done!

I found the problem :slight_smile:
The EventListener Class I originally defined for use with ServerSocket and Standalone.
With Standalone a listen is executed after close!

When testing with ServerSocket I have created the standalone variant of the EventListener, which naturally leads to the described problem! (Sockets remain listen)
One more question about my AddSocket with TCPSocket Pool:

If mSockets.Ubound > 0 Then
  // Pool benutzen, freien Socket suchen
  For i As Integer = 0 To mSockets.Ubound
    If Not mSockets(i).IsConnected Then
      mCurrentSocket = i
      Exit For
    End If
  Next
Else
  // TCPSockets Pool erzeugen
  Dim ret As EventListener
  For i As Integer = 0 To 10
    ret = New EventListener(i, False)
    mSockets.Append ret
  Next
  mCurrentSocket = 0
End If

Return mSockets(mCurrentSocket)

Is the search for a free socket correct?
Thanks again for your answers

Since your sockets are now being released properly, there’s no need to maintain your own pool. Just create new ones as the serversocket requests them.

The real problem is unfortunately still present.

I wrote an EventSender test program to test the EventListener.
The EventSender periodically sends an HTTP NOTIFY message (for example every 1 second) to the EventListener, which returns a response.

Behavior of the EventListener:
If the EventListener is the active program, the transfer works properly.
If the EventListener is NOT the active program, it does not respond as soon as I activate the window of the EventListener, the transfer will work again.
What could be the problem?

Is any of your socket code tied to the interface? Maybe you could try just outputting to a log file or something similar to make sure.

[quote=337511:@Romeo Giezendanner]The real problem is unfortunately still present.

I wrote an EventSender test program to test the EventListener.
The EventSender periodically sends an HTTP NOTIFY message (for example every 1 second) to the EventListener, which returns a response.

Behavior of the EventListener:
If the EventListener is the active program, the transfer works properly.
If the EventListener is NOT the active program, it does not respond as soon as I activate the window of the EventListener, the transfer will work again.
What could be the problem?[/quote]
Is your EventListener app running on macOS? If so, it’s probably going into AppNap mode.

Yes
What can be done about it?

Disable it as needed
See this post https://forum.xojo.com/conversation/post/250882

[quote=337657:@Norman Palardy]Disable it as needed
See this post https://forum.xojo.com/conversation/post/250882[/quote]
Thanks Norman, it works.
I use the NSProcessInfo from Sam.