TCPSocket Won't Close.

I have a Windows desktop client app that is connecting to a server app via a TCPSocket. The client app is also using a shell to send commands to a exe file that controls a LCD screen. This exe was not created with Xojo. I can only close the TCPSocket on the server side after I have sent the command to the exe file through the shell to close. I can accomplish this with a thread or with two buttons while the app is running but I want to be able to close the TCPSocket on the server on app close. I’ve tried and tried to work something out in CancelClose but I can’t get it working. Here’s the code I have in a thread that works if the app is running. Can anyone give me some advice on how to make this same code work in the CancelClose event of the main app window? Thanks!

uShell.WriteLine "" me.Sleep(2000) sckGM.Close me.Sleep(2000)

This is how I am using the shell that seems to be blocking me from closing the socket.

On window open:

uShell = New tShell uShell.Mode = 1

uShell is a global shell property.

Close isn’t the same as “disconnect”
There can be a delay in the disconnect occurring (up to a couple minutes)
If you want it to disconnect immediately try setting it NIL

Thanks Norman, it’s weird though it closes immediately as long as the LCD exe file isn’t running via the shell when I send sck.Close. :confused:

That makes sense
Tcp is odd
You have no way to ask much about the state of the world with them until you try to do something and then it fails.
And then you handle the error
The typical one is “is the other end still there ?” and one you cant tell until you try to send something then deal with the resulting error if its not

In this case it more than likely goes into a state where you cant write but doesn’t close because it IS connected and then it eventually times out and closes
Thats why niling the instance makes it immediately drop regardless - everything HAS to be torn down for it to be set to nil which means it WILL close immediately

@Norman Palardy I tried:

sckGM = nil

just now several times on close and the socket is still connected on the server side. It’ll just sit there indefinitey and display connected on the server until I close the LCD exe and send sckGM.Close.

Can you tell me how to make the main app window execute my thread code on CancelClose?

I’ve tried:

[code]if appQuitting = True Then
Return True
Thread1.Run
End If[/code]

But it just closes the window and hangs, as far as I can tell the thread never really executes anything. Eventually I just have to close it via the debugger. Thanks!

The method will stop at Return True - your Thread1.Run will never happen.
Swap the order.

I tried both ways neither one does anything. If I return False it doesn’t even hang it just immediately closes.

Also I probably should have mentioned the Server app wasn’t written by me or in Xojo but in VB.NET.

@Tim Parnell Oh I misunderstood you. You meant run the thread before Return True. Thanks. I tried that too just now but my app window just closes and the debugger just hangs until I close the tab. I added QUIT at the end of my thread to make sure and like I said it just hangs until I manually close the debugger tab.

Thread1.run

uShell.WriteLine "" me.Sleep(2000) sckGM.Close me.Sleep(2000) QUIT

CancelClose

if appQuitting = True Then Thread1.Run Return True End If

I know the thread code will accomplish what I want because if I put it in a button and execute the thread it works. I just can’t get it working in Close or CancelClose. :confused:

Thanks for all the help! :slight_smile:

You can pause your app from the IDE while it’s hanging to try to figure out why it’s hanging.

My guess is that you didn’t provide it a way to be like “yes, please actually close.”
When your thread finishes and it calls Quit, it’s asking the window if it can close, and the window is telling it not to during the CancelClose event and starting the thread again. An infinite loop of not being able to close.

Thanks! How do I return False from the thread to the CancelClose event?

It’s weird Close will execute the shell command to close the exe but CancelClose will not, even if I do it in the event itself and not via a thread. Unfortunately though on Close event the socket still remains connected on the server side when told to close. :confused:

You may want to check out the manual. It covers all kinds of things so you don’t have to guess.

Create a property on the window, a boolean called something like bSocketClosed. In your thread, at the end (before Quit,) set bSocketClosed to true.

In your CancelClose event, change if appQuitting = True Then to if appQuitting = true AND bSocketClosed = false then This will make it so after the thread has closed the socket your CancelClose event won’t cancel the app from closing.

Thanks I already tried that and it still didn’t close, and trust me I’ve looked at the manual.

Can anyone explain why an Asynchronous shell mode execution of a exe file that is looping waiting for a command would block a TCPSocket from being able to close?

It is definitely the exe file that the Asynchronous shell is executing that is blocking my app from closing this TCPSocket on the server side.

The same exe file that is running is also what is preventing my app from closing on the QUIT event in the thread I am running on CancelClose.

If I end task the exe file in task manager my app will immediately close when it’s sitting there hung on CancelClose.

I wish there was a dll available for this LCD screen and I didn’t have to use their c++ compiled exe. It’s breaking my app! Grrrrr.

Thank you @Norman Palardy and @Tim Parnell for all your advice and help. I appreciate it. :slight_smile:

[quote=312150:@Geoff Haynes]@Norman Palardy I tried:

sckGM = nil

just now several times on close and the socket is still connected on the server side. It’ll just sit there indefinitey and display connected on the server until I close the LCD exe and send sckGM.Close.[/quote]

Right
A socket disconnecting doesnt “DO” or send anything
It just drops off and if the server never tries to send something to the client then the socket will appear to be connected

What I wrote earlier about “TCP has no idea until you try to USE it (read or write)” that something like a disconnect has happened

Thanks Norman. Unfortunately the person who wrote this Server app has the source and is long gone. Must be some kind of keep alive, the socket never times out, ever. My main issue is this other exe. While the shell has it running I can’t even put sck.close in a button and get the socket to close. If I send the close command to the LCD screen exe via the shell while the app is running I can then FINALLY close the socket on the server side. But for whatever reason, I can’t get the exe file to exit with the same command on CancelClose. It works in Close, but then the client app closes too fast for the socket to get the close command. I’m forced to look at this c++ source code and attempt to find a way to get this exe file to close in a more reasonable manner. Again, thanks for all the help.

Are you sure Me.Sleep isn’t the cause?

I was finally able to get the socket to close on app close by using the CancelClose event of the app instead of the main app window. I created a custom timer class and created a timer property in app to use it. I added a boolean property in app and used it like this.

App.CancelClose

if isShuttingDown = False then ThreadA = New ThreadAAA ThreadA.Run Return True else QUIT end

ThreadAAA.Run

sckGM.Close me.Sleep(2000) App.isShuttingDown = True

But what really made the difference was instead of sending the command to shut down the LCD exe program via the running shell in main app Window.Close I manually shut that stubborn exe down with taskkill.

Main Window.Close

Dim mShell as New Shell mShell.mode=0 mShell.Execute("taskkill /F /IM HID*") mShell.Close

Thanks again for all the help guys. :slight_smile: