TCPSocket connect in a thread

Doing searches through the forums seem to show that trying to use threads and sockets seem to be fraught with problems, but we seem to have a new problem which has only occurred recently with newer Xojo versions.

We have a socket.connect command inside a thread. The port and address is set just before the connect is called.

If socket.connect is called on a PC, everything works.
If socket.connect is called on a Mac and connect to another mac, everything works.
if socket.connect is called on a Mac and connects to a remote(via internet) PC, everything works,

Now things get weird.

if socket.connect is called on a Mac and connects to a local(VM) PC we get a socket error 22 immediately on the connect.
If I pause(in the IDE) on the socket.connect line, then press continue, everything works, every time.
If we add a app.doevents(100) before socket.connect everything seems to work.

It appears that there takes an undetermined amount of time to create the socket, which causes a problem on Mac. The error 22 is immediately returned after socket.connect. If I add a breakpoint on the line after socket.connect, the error occurs before that line is reached.

We’ve used this connection type for years, but it’s only recently that we have a problem. We’re not too bothered about dataavailable being run on the main thread, but it would be good to have the connect run on a thread so that the UI is not locked during the connection process.

Regards,

Lee

First, is your VM in network bridge mode?

If yes, you should file an Issue report with the above explanation and a sample app pair of apps (simple client and simple server) and instructions on how to reproduce the case.

I should not have mentioned the VM because the customers with the problem are using a Windows Server, but on the local network. We are doing testing on a VM, just because that is how we are setup. We have tried bridged and Ad-hoc with the same result.

It seems to be down to speed. A fast local network connect fails, a slower internet one is ok.

Regards,

Lee

You need to select the right metwork interface on the socket if there are multiple. This could be the case in a server.

<<
We have a socket.connect command inside a thread.
The port and address is set just before the connect is called.

Most all connections works ok, as:

If socket.connect is called on a PC, everything works.
If socket.connect is called on a Mac and connect to another mac, everything works.
if socket.connect is called on a Mac and connects to a remote(via internet) PC, everything works,

Except:

If we try it in some fast environments with fast networks. We have cases failing to connect to Windows servers, we get a socket error 22 immediately in those environments

We can reproduce it if we try, for example, a socket.connect() on a Mac, pointing to a local Windows in a VM, we get a socket error 22 immediately.

But if we break debugging on the socket.connect line, then press continue, everything works, every time.

If we add a app.doevents(100) before socket.connect everything seems to work too.

It appears that the socket preparation and the socket.connect() have troubles with the combination fast machine + fast connection. Some kind of asynchronicity troubles comes in when preparing the socket, just before the connect, and we needed to yield some time to events/socket GET READY BEFORE the connection, or it fails.
>>

Open an issue report.

Clearly a Xojo bug isolated to “just under fast processing environments with fast connections”.

Make sure to provide sample apps and that info above in the modified quote for better understanding. Take action soon and it may be included in the upcoming R1 release of the 2023.

Our Macs have both wired and wifi network connections. I’m not sure about the customers though.

I’ll see if that makes a difference, although we’ve never had to set that before. All network communications have been automatic.

Regards,

Lee

One of the things we did try was to set the address in the constructor so that’s definitely run on the main thread in case the address was used to decide the network interface. This made no difference.

Regards,

Lee

Have you tested each type of connection (wi-fi vs. wired)?

It’s easy to see that the problem seems tied to preparation and asynchronicity just after the change on the target IP and Port. Maybe isolated on Mac clients to the Windows servers in some way?

Xojo need to to provide the socket all necessary resources and time to complete all the necessary pending settings under the hood before starting the real socket.connect() job.

Anyway,

Mac to PC via VM doesn’t really use any real connection. Customer (Mac to Real PC) is all wired.

Mac to PC via the internet is wired

There’s no event at the PC end when we get an error 22.

The events I said are internal events, on the client side.

That’s something at system/Xojo level. Bug.

Probably at main thread level it would work, not sure, but in a thread, Xojo may need to process things differently of what it is currently doing. All I see is that if you let the event loop / system threads have some time, before the connection, the connect command receives the socket ready, otherwise it’s not ready yet and just fails.

How to fix? Let Xojo know. Let them replicate and fix.

That’s not how sockets work. All of their events fire on the main thread.

Something that’s not clear from your description though… on the computer you are connecting to, are you using a ServerSocket or just a TCPSocket? On the From side are you creating a new socket each time or just reusing the one from the previous attempt?, The reason I’m asking is that Error 22 indicates that the socket disconnected. Which makes me wonder if what you are seeing is the disconnect of the previous socket connection, not the one that you are currently establishing.

1 Like

We are connecting to a Xojo ServerSocket. As far as I am aware, this is the first connection using the socket, so there is should be no reusing an old socket.

But have you tried using Wifi vs. wired connection from the machine hosting the VM to the local network?

The VM and Mac are on the same computer. VM network adaptor is set to ‘Auto Detect’, which, if is uses the same priority as the Mac does is wired.

What he does (in a thread):

sock.RemoteAddress = "192.168.1.123"
sock.Port = 9876
Call sock.Connect() // Error 22

What may be going on:

sock.RemoteAddress = “192.168.1.123”

  • queue some event due to this change

sock.Port = 9876

  • queue some event due to this change

Call sock.Connect()

  • Some connection actions starts…
  • there’s some time available here to process some events if there are some
  • Hey, address/port change events arrived in the middle of the negotiations, connection invalid, abort error 22

And this behavior MAY BE exclusive for the Mac client.

Lee said the PC client just works.

If the PC part works as is. Maybe Xojo could make both working.

Hello, bug report? :thinking:

Which event do you have in mind? The only one that makes sense is Error, in which case that should be available to happen right after the assignment provoking it. So have the thread sleep for some msec after each of these two assignments and see where the problem occurs.

Abstract ones. Internal ones. Events as I said related to target ip:port changes. Who can answer it correctly is William in the bug report on what’s going on.

Or just ask to investigate and fix.

Not sure if such sleep would help, not help, or create random instability depending on what machine it runs.

I have two suggestions.

First, as you’ve discovered, the debugger can have odd effects when you are troubleshooting Socket events. It can cause things to work during the debug session that fail during runtime. To avoid this interference, I suggest you create a logging system that keeps exact track of events as they happen. For example, your Socket.Error event might simply have a line of code that says “logSystem.LogText(currentDateTime+” Socket got error “+errorNumber)”. Put similar code in Connected, DataReceived, etc. During debugging, clear all your breakpoints and trigger the problematic code, letting it run (and fail). Then, break in to the debugger and look at the log text. You’ll have a much better idea of what is going on.

Don’t forget: if you have multiple Sockets making connections, you’ll want to give them each a unique ID and log it so you can see which events happened to which sockets. You may also want to set up this kind of logging system on the server end.

Second, if you need a temporary workaround until you can get a full resolution, you can try using Timer.CallLater with a very brief period (even 0) to call Socket.Connect, since it seems like a teensy delay is all that is needed. Using a Timer like this allows Xojo’s internals to “catch up” and do whatever machinations seem to be necessary in this situation. And if this trick works, you really should file a very specific bug report, because this is not how it is supposed to work. :slight_smile:

…and get rid of any calls to DoEvents that you have. It causes issues like this where things don’t fire the way you would expect.

1 Like