TCPSocket reconnect issue on Mac

Well, either way it doesn’t work. I just tried it. The behavior is identical. I added:

if Window1.ClearCoreServer.IsConnected then
  break
  Window1.ClearCoreServer.Disconnect
end if

if Window1.LocalServer.IsConnected then
  break
  Window1.LocalServer.Disconnect
end if

To the App.Close event of the application linked to in the original post.

I launch the application, initiate the connection, fire up the MCU, send it a few commands to verify both directions are working, then quit the app. Launch it again, initiate the connection, and it’s dead. neither of the conditions above is ever tripped, since I never hit either break, even though there’s very much an active connection at the time.

In the Action event of a button:

ClearCoreServer.Address = clearCoreIP
ClearCoreServer.Port = clearCorePort.ToInteger
ClearCoreServer.Connect

if ClearCoreServer.IsConnected = true then
  lClearCoreServerStatus.TextColor = color.rgb(0,200,0)
  lClearCoreServerStatus.Text = "Connected"
else
  lClearCoreServerStatus.TextColor = color.rgb(200,0,0)
  lClearCoreServerStatus.Text = "Not Connected"
end if

LocalServer.Address = desktopIP
LocalServer.Port = desktopPort.ToInteger
LocalServer.Listen

if LocalServer.Port > 0 then
  lDesktopServerStatus.TextColor = color.rgb(0,200,0)
  lDesktopServerStatus.Text = "Listening on " + desktopIP + ":" + LocalServer.port.ToText
else
  lClearCoreServerStatus.TextColor = color.rgb(200,0,0)
  lClearCoreServerStatus.Text = "Not listening"
end if

See Big Sur ServerSocket Trouble which may be the same issue

Interesting, but it sounds like your solution is similar to the .disconnect suggestion above. In my App.close event when i test for .isconnected = true it just passes by. See the post just a couple above yours. So neither TCPSocket.close nor TCPSocket.Disconnect would get triggered with that test.

This seems to be an MCU issue. I don’t think it’s a xojo issue, even if it’s macos only. You mway want to double check the MCU is closing the socket/client properly and waiting for a new one properly.

MacOs can be slow in allowing ports for resue again. And some ports may be blocked by a firewall or they may get owned by another process. Could be it bit i don’t think this is.

Is this MCU an esp32 by chance?

How many minimum sockets and maximum sockets does your xojo server have?

And how many can the MCU actually have at a time?

A few thing to check:

  • Firewall (tried it turned off?)
  • Port usage, it could be in use/registered at iana
  • you may need to have a codesigned build app (at least run it codesigned once)
  • Try a high port number 10123 or something when possible.

It’s a SAME53N19A (ARM Cortex M4F). The unit we’re using is this one.

Whatever the default is - I don’t see where I can configure a socket count with TCPSockets.

I’ll ask our firmware developer.

Yes.

It doesn’t appear to be. Some things use it unofficially, but my understanding from the firmware developer is that Teknic encourages only using port 8888 for the server running on the ClearCore, though it can use any other port as a client. I don’t have more information than that.

But this wouldn’t explain why it works perfectly as long as I follow specific steps, would it? It’s only when I quit my app and restart it that I begin to have issues. I’m not sure I see how code signing would come in to play here since it does work some of the time.

I’ll see what I can do with this. We have a provision in the system that allows for setting different port numbers, but I need to find out what the ramifications are of using a different port than 8888 for the server.

You mentioned an “Application server” ? So is it a single socket (listening) or is it a server socket that is listening on your xojo app ?

My reading of the docs is that ServerSocket is used if you’re making a server that will have multiple connections from multiple locations and that TCPSockets are more for point-to-point connections, and that TCPSockets add a layer of reliability with flow control and “more graceful” disconnects (per the documentation). As such, we are using the TCPSocket Class. I guess that means a single socket? I haven’t tried to connect to it from another machine.

If it’s a single socket though, why does the server on the Xojo app work after the first (but not subsequent) quit/restart cycle? I would think it would not work after I restart the app, but it does. It’s only on the next cycle that both the server and the client in my app appear to be disconnected entirely from the ClearCore.

Well then, disconnect and create a new instance of your single socket and try that.
MacOS is alway a little holding onto things, the port may be kept in use for longer than you expect. That’s just what apple happens to do often. Not sure why or how it happens.

New Instance of Xojo tcp sock connect > MCU > process > disconnect > (go back to “New Instance of Xojo tcp sock connect”) etc…

Hmm. When you say “Disconnect” here, do you mean calling .disconnect on the TCPSocket, or are you referring to quitting/restarting the app?

When I try to call either TCPSocket.disconnect or TCPSocket.close in the App.Close event on the TCPSocket that is connected to the ClearCore, it doesn’t seem to make a difference in terms of actually severing the connection cleanly (assuming that’s the problem here)

When I quit the app and relaunch it, then try to reconnect, the app is being bound to a different port from the OS than in the first session, which I think is what you’re telling me to try to do here, right? See the (first) screenshot I posted above from PacketPeeper. When it reconnects to the ClearCore after quitting, it’s being bound to a different port internally on the mac.

Calling .Disconnect is the only way to let the other end know you have disconnected. Otherwise the system will guess that you disconnected after a certain timeout (system provided)

If that’s not disconnecting (or showing up as disconnecting in wireshark or so) then that would be considered a bug. But as we use the same principles, we’ve not yet seen such bug or noticed it.

When I say “it doesn’t make a difference in terms of actually severing the connection” I’m making an assumption that the problem I’m seeing is an orphaned connection preventing me from reconnecting later. I don’t really know that for sure.

The port binding is normal wen you connect (calling .Connect) client tcpsocket:

  • Your xojo tcpsocket is given the remote port num
  • tcpsocket connectes to it from a local port (that’s assigned by the system) to the given remote.
  • Your .Port will give you the port you are bound to (or listening to when you used .Listen).

So you use TCPSocket.Connect (not .Listen) you get TCPSocket.Port that is should be connected to.
If you use .Listen that’s a whole different case.

Then try not to use .Disconnect but use .Close and then reinstantiate the socket.
That may fix your issue.

From the docs (https://documentation.xojo.com/api/networking/tcpsocket.html) :

TCPSockets can be orphaned. An orphaned socket will keep a lock on itself after you call either the Connect or Listen methods. The socket gets unlocked when it has been disconnected. This means that an orphaned socket will continue to work so long as it is connected. This also means that you need to call the Close method before its lock will be released.

If you orphan a socket, you need to be certain that the socket will get a disconnect message from its connection at some point. For example, some web servers will not release a socket once the data has been transferred to it (for efficiency reasons). When you are done with the socket, it will remain active and connected unless you explicitly call the Close method of the SocketCore class. If you think your socket could be in a state in which it is left open, keep a reference to the socket around somewhere and use the Close method to terminate the connection. Calling the Disconnect method also applies instead of calls to the Close method.

I think part of the confusion here is that we’re doing both - The Xojo app is running a client that talks to the ClearCore server on its port 8888, but the Xojo app is ALSO running a server, on local port 8889. We are seeing slightly different issues on each of these:

On the Xojo Client, it is unable to reconnect to the clearcore after the first App quit/relaunch cycle.

On the Xojo Server , the connection is gone after the second quit/relaunch cycle.

I thought about that this morning, and added an explicit .close for both the client and server to app.close, but it doesn’t change the behavior at all.

Do you have the plist key: NSAllowsLocalNetworking ?
We had to add that one to overcome some issues in socket usage on some macbooks.

I did not. Never done that before since most of our apps get built for Windows (or the mac apps haven’t needed any plist keys). I followed the instructions in the docs and added an info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>NSAppTransportSecurity</key>
			<dict>
  				<key>NSAllowsLocalNetworking</key>
     			 <true/>
			</dict>
	</dict>
</plist>

Added it as a build copy step to the App Parent Folder and ran it, but still the same behavior.

At this stage, i need to just get back to work on the app rather than playing around with this all day, since ultimately, we need it to work on Windows, and it already does. I’m happy to keep testing stuff as I have free time, but for now I have a bunch of other stuff I need to deal with.

Thanks for all the suggestions.

1 Like