Xojo IPCsockets not working.

Tested on Xojo 1, various RS versions for OS X 10.6.
Other OS targets untested/unknown.

IPCsockets don’t seem to be working.
When trying to run the included example I get a 103 NameResolutionError error when attempting to have the IPCsocket listen.
The IPCsocket example is located in the communication folder inside the internet subfolder which is a strange place since IPCsockets don’t use the internet AFAIK.

IPCsockets are used for [I]nter [P]rocess [C]ommunication on the same machine.
This socket is used when you need your application (process) to communicate with another process.
An example for this is when you have a GUI based desktop application that off loads work to one or more console applications. IPCsockets are used for them to communicate with each other.

About a two weeks earlier I had done more IPCsocket tests on different versions of RS and had other IPCsocket problems. I don’t have my notes in front of me right now so I don’t have details but I’m not sure if any of the versions of RS I tested IPCsockets worked correctly. I was testing both desktop and console applications.

Has anyone else experienced issues with IPCsocket?

Btw, I see many categories for this forum but I don’t see a networking or communication section so I am not sure whether to post this in the general section, the OS X section or somewhere else.

Having a networking or communications section of the forum would be appropriate and prevent similar or duplicate posts regarding the same issues under different operating systems.

Why was the networking section removed and why isn’t there a replacement?

Hi Mason,

You look like you know what you’re doing, so please don’t take this the wrong way, but have you set the path to an appropriate value that is accessible by both the client & server?

I have IPC Sockets working on Windows 7 and am happy to share my very simple client/server demo apps if you think that would help.

HTH

Wayne

Hi Wayne thank you for your reply.

I didn’t play with them for a while but yes I believe I did have the same path for both IPCsockets (listen and connecting). I can check this out later. Also note that just clicking the ‘listen’ button on the Xojo example throws that specific 103 error I mentioned. I believe I experienced other errors with different versions of RS but would need to either test again or reference my notes to be more specific.

Btw, IPCsockets are meant to be used on the same machine. Not a separate client and server.

Please post your code I’ll give it a try :slight_smile:

TY.

Hi Mason

Have a look at this IPCSocket there are two projects client & server. You will need to adjust the paths - very windows centric sorry.

HTH

Wayne

Hi Wayne.

Thanks to your example and more testing I’m making some progress but things may still not be working correctly.

Additional errors I was receiving was a 105 AddressInUseError. Strangely this 105 error would happen every other time when being run from either the IDE or a build. The alternate run would be ok and not throw me the 105.

When that error occurred the listening IPCsocket would not work so a connection would not be made resulting in a failure.

The documentation does not clearly say why this error happens or how to correct it but I figured out it’s because I wasn’t deleting the created socketfile before trying to run or rerun the listening process. The documentation also doesn’t say why sometimes the IPCsocket listening process will work but then when rerun it fails throwing the 105 error but I figured this out too.

The lack of consistently throwing errors complicated this situation as did the documentation’s suggestion of hiding the socketfile from visible view. It turns out the IDE and build are secretly deleting the existing socketfile if one exists after it throws the 105 failure. More specifically it’s probably when the IPCsocket calls .listen on a pre-existing socketfile should one exist. That means if you first run a good IPCsocket example that calls .listen it won’t throw you a 105 and your project should accept a connection. But, the next time you run the same example and now the socketfile exists you get tossed the 105 and your process will not accept a connection. However the sneaky IDE and build doesn’t tell you it secretly deleted the offending socketfile which means the developer has no idea why it’s failing.

Doing this over and over while checking and changing your code trying to figure out what’s going on is about as much fun as smashing your head into a brick wall.

The documentation section pertaining to this matter for IPCsocket currently says :
“The file might remain in existance even after closing the connection, so you should delete any leftover files from previous connections when you make a new connection.”

It doesn’t mention anything about causing errors, not working correctly, or alternately working then throwing errors every other run.
The wording wrongly indicates that you might want to clean up the left over files if you don’t want them hanging around.

The documentation should be amended to state something like I’ve written below :

ERRORS :
105 AddressInUseError :

If you receive a 105 AddressInUseError while using an IPCsocket (please run to the nearest wall and smash your head into it twenty times) it is because there is an existing socketfile of the same name which has not been deleted before your IPCsocket listening process is trying to call .listen. When receiving the 105 error your listening IPCsocket process will not work and no connection to it can be made. To prevent this error you must first delete an existing socketfile of the same name in the same location before your IPC listening socket process tries to create and call .listen on it. You may do this by having your IPCsocket listening process delete the socketfile after it’s finished it’s job and before it quits. Alternatively, when your IPCsocket listening process is first run you may want to check if there is an existing socketfile of the same name in the same location and if one exists delete it before your process creates the socketfile and calls .listen.

Please note you only want to delete a pre-existing socketfile for a process that intends to receive a connection by calling .listen. You do not want to check for and delete an existing socketfile before making a connection using an IPCsocket in a client that is calling .connect because this may delete the correctly created and necessary socketfile created by the listening IPCsocket which is required for successful communication.

Yes this was a PITA to deal with and I wasted hours figuring it out.

Oh sorry that last part probably shouldn’t go in the documentation :wink:

That’s the wordy version for people who like more details. A truncated version could alternatively be used :

ERRORS :
105 AddressInUseError :

Target: Mac OS X
Build : Console
Cause : Pre-existing identically named and identically located socketfile conflicting IPCsocket .listen call.
Solution : Delete any pre-existing identically named and identically located socketfiles before trying to call .listen on them.
Confirmed : OS X 10.6


Wayne, we’re not done yet!

More IPCsocket strangeness :

After making the needed path modifications and 105 solutions to your example, it now seems to be connecting and sending the timestamp back correctly (thank you ) but I’m getting a strange

msg upon connection.

I don’t see anything in the documentation that says IPCsocket is supposed to output and it doesn’t make sense that it should especially on a successful connection.

Anyone know why IPCsocket is outputting a message upon connection?

I’m wondering if IPCsockets are reliable enough to use on Mac?

We customers should be able to append to the online documentation.
It would save other developers valuable time, stress and improve this product.

Why can’t customers append the Xojo documentation with notes, code and example projects?

You can. Simply ask customer service for a login to the wiki.

IPCSockets better work or we could not debug apps :stuck_out_tongue:
Its how we star & have your app being debugged talk to the IDE

I use a very complex messaging through (multiple) IPCsocket on Mac and it works properly. The only thing I had to do is polling the socket more frequently with a timer, because of the built-in latency of IPCsockets in GUI apps.

are you using the TEMP folder or some other folder of the system?

Thanks guys for helping.

Hi Norman.
The xojo IPCsocket example project for Mac does not work at all in Xojo release 1 which is the current version.
It has a bug which I’ve found and fixed. It was an easy fix, no big deal. The example doesn’t seem like it was tested on Mac because as soon as you click the listen button it has an error and will not work.

The author was using the wrong path type. For Mac and Linux it was .Shellpath. For Windows it was .Absolutepath. Change the path type to .NativePath and the desktop IPCsocket example appears to now be working correctly.

Use this code in the window’s open event :

#If TargetWin32 Then
CommSocket.Path = SpecialFolder.Temporary.Child(“com.mydomain.test”).NativePath
#Else
CommSocket.Path = SpecialFolder.Temporary.Child(“com.mydomain.test”).NativePath
#Endif

Some other IPCsocket issues I’m wondering about are below.
Any ideas on why is being displayed on connection for IPCsocket console apps?
Why does the IDE, console, and desktop builds (for Mac) delete an existing socketfile? Why aren’t we told about this? Not knowing it does that really made it a time consuming pain to figure out why the IPCsocket wasn’t working correctly.

Massimo thank you for sharing your experience. I’m glad to hear IPCsockets are working well.
Are you deleting your socketfile ?
If you are not I don’t understand how you’re not getting the 105 error and having your listening IPCsocket fail?
Could you try using a console IPCsocket to listen and take a connection on Mac and tell me if you get a message on connect?

Hi Tim. That’s good the wiki allows us to add to it. I didn’t know the wiki could hold an example project or maybe you didn’t mean that last part?

Not sure if I will ask for a login right now. So far nobody’s commented on my helpful notes so I’m assuming nobody cares and I’m short on time. I would also like someone with more experience to verify what I wrote is correct before it would be added to the docmentation. Xojo is welcome to use what I wrote in the documentation to help other developers if they want.

Derk thanks for participating and trying to help. As far as I know that shouldn’t make any difference. What I think matters is having correct permissions. But yes, I’ve also experienced the same results when using a temp folder or other locations.

[quote=19838:@Mason Mack]Thanks guys for helping.
Hi Norman.
The xojo IPCsocket example project for Mac does not work at all in Xojo release 1 which is the current version.
It has a bug which I’ve found and fixed. It was an easy fix, no big deal. The example doesn’t seem like it was tested on Mac because as soon as you click the listen button it has an error and will not work.
[/quote]
Please make sure you’ve filed a bug report against the example for this

[quote=19838:@Mason Mack]Some other IPCsocket issues I’m wondering about are below.
Any ideas on why is being displayed on connection for IPCsocket console apps?
[/quote]
Not sure since I’d expect the IDE to also issue a warning if it were just IPCSocket related

[quote=19838:@Mason Mack](for Mac) delete an existing socketfile? Why aren’t we told about this?
[/quote]
There’s no code in the IDE to delete an existing IPC Socket.
However if the socket is not in use it can get overwritten but I doubt you’d be using one with the same name.

[quote=19855:@Norman Palardy]Please make sure you’ve filed a bug report against the example for this
[/quote]

How does the point system work?

I don’t want to use up valuable points for something like this.

I want to be sure I can file a report without using any of my points?

Is this explained in detail anywhere in the documentation?

[quote=19855:@Norman Palardy]
Not sure since I’d expect the IDE to also issue a warning if it were just IPCSocket related[/quote]
Since this is while using a console IPCsocket the appears in terminal. Don’t think there’s any warning in the IDE.

[quote=19855:@Norman Palardy]
There’s no code in the IDE to delete an existing IPC Socket.
However if the socket is not in use it can get overwritten but I doubt you’d be using one with the same name.[/quote]

It’s not the actual socket, it’s the socketfile. Not sure if that was understood.
The socketfile is visible or it can be viewed in terminal. After an IDE or build run an existing socketfile gets automatically deleted when the 105 error happens.

If you did understand it’s the socketfile and you meant overwritten I would think an exactly named duplicate socketfile would appear. It does not. The socketfile seems to get deleted.

[quote=19857:@Mason Mack]How does the point system work?

I don’t want to use up valuable points for something like this.

I want to be sure I can file a report without using any of my points?
[/quote]
Yes
Your Top 5 are what get your points
But you can submit as many reports as you want

[quote=19857:@Mason Mack]
Since this is while using a console IPCsocket the appears in terminal. Don’t think there’s any warning in the IDE.
[/qupte]
This is in your console app that you’re trying to open a new IPCSocket ?

Again - no code to delete anything connected to the IDE’s IPCSockets.
But if there’s an error & the socket closes then the underlying file would disappear.

You can’t attach an actual project file to a wiki entry, but if you paste in most of the code, you’ve effectively posted the project.

I just asked about the temp folder, cause it has all permissions as far as i know. It’s strange that it’s not working for you but i have seen some other problems as well…

The problem is on OS X 10.6 the Temporary folder includes characters that are escaped when using ShellPath… The IPCSocket class requires a POSIX path (not escaped). That’s why FolderItem.NativePath was added to properly support OS X paths. In fact the example code no longer needs the #If TargetWin stuff anymore because .NativePath does the right thing for all platforms. (ShellPath is still needed when using the Shell for a porper escaped path of course).

I filed a feedback request to update the wiki docs a few weeks ago, but forgot to check or suggest the example projects be fixed.

Thanks Jason.

Anyone know why the message is being displayed on connect when a console IPCsocket connects?

[quote=19838:@Mason Mack]Change the path type to .NativePath and the desktop IPCsocket example appears to now be working correctly.
Use this code in the window’s open event :
CommSocket.Path = SpecialFolder.Temporary.Child(“com.mydomain.test”).NativePath
[/quote]

Doesn’t this fail 100% of the time if two separate apps are calculating .Path? From what I see, SpecialFolder.Temporary on 10.6 and up gives a somewhat random path in the OS-defined temp folder. So when I tried it, my listener app calculated one Path and the connector calculated another. So no connection. For example:

  1. .Path = /Volumes/Snow Leopard Drive/private/var/folders/uT/uTwfvrgyHIKTQ8bDZempWU+++TI/-Tmp-/TemporaryItems/com.mydomain.text

  2. .Path = /Volumes/Snow Leopard Drive/private/var/folders/aWT/hTidkglYHHT+++HJTYE/-Tmp-/TemporaryItems/com.mydomain.text

So I don’t see how using Temporary can even work at all. I write the connection file to SpecialFolder.ApplicationData, to my company folder I write into there. That way I’m guaranteed the same file every time. I also delete the file explicitly on the Listen side, before I Listen.

Also, just some questions, does data passed through IPC get written to this connection file, or is it passed via memory? And, is there a limit on the size of the string that can be passed? I have chunks up to 65536 bytes to be sent.

[quote=22661:@Garth Hjelte]
Also, just some questions, does data passed through IPC get written to this connection file, or is it passed via memory? And, is there a limit on the size of the string that can be passed? I have chunks up to 65536 bytes to be sent.[/quote]

At the very lowest level on Unix based system IPCSockets are file handles - but that does not necessarily means that data hits the disk.
I’ve passed a lot more than 65536 bytes through them
Debugging a locally running app uses them for EVERYTHING you see in the debugger (except the source code)

Let me start off by saying that most of this only applies to OS X and Linux, given Windows’ lack of support for AF_UNIX sockets.

[quote=undefined:undefined]ERRORS :
105 AddressInUseError :

…[/quote]

You’re right, the docs definitely should address this situation better.

I’ve never seen this before (without someone explicitly calling System.DebugLog). If anyone does, please paste the full message from console.

[quote=22661:@Garth Hjelte]Doesn’t this fail 100% of the time if two separate apps are calculating .Path? From what I see, SpecialFolder.Temporary on 10.6 and up gives a somewhat random path in the OS-defined temp folder. So when I tried it, my listener app calculated one Path and the connector calculated another. So no connection. For example:

  1. .Path = /Volumes/Snow Leopard Drive/private/var/folders/uT/uTwfvrgyHIKTQ8bDZempWU+++TI/-Tmp-/TemporaryItems/com.mydomain.text

  2. .Path = /Volumes/Snow Leopard Drive/private/var/folders/aWT/hTidkglYHHT+++HJTYE/-Tmp-/TemporaryItems/com.mydomain.text

So I don’t see how using Temporary can even work at all. I write the connection file to SpecialFolder.ApplicationData, to my company folder I write into there. That way I’m guaranteed the same file every time.[/quote]

Are the applications running as two different users? Each user has their own temporary folder, but as far as I remember, they should be the same across their processes.

I’m not sure precisely what you mean by ‘delete’, but the ‘right’ thing to do is to call unlink (via declares) and not FolderItem.Delete. When we close a listening IPCSocket, we do call unlink, but that doesn’t handle an abnormal exit (by a signal, crash, etc).

In practice, they don’t ever hit disk. I’m not sure if the underlying API guarantees this implementation or not, but I wouldn’t worry. What can happen is that the kernel send buffers for the socket fill up and we queue the data up an in-process buffer. When we notice that we can send more data through the socket, we do so until the kernel buffer is full, remove from our buffer, etc.

Since I’m sure everyone has stopped reading by now, I’ll add some important information here in bold:

  • IPCSocket paths have a length limit. On OS X, this is 103 bytes (encoded in UTF-8) and similar on Linux. Prior to 2013r3, exceeding this will cause crashes. Case #22697.
  • Like the rest of our sockets, IPCSockets are driven by polling and require the event loop to be running or manual polling. It’s an unfortunate situation and one I’d love to fix in the future.
  • Windows IPC sockets use a TCP connection bound to localhost with a port derived from the path due to the aforementioned lack of support for AF_UNIX sockets. This means that they not do not have the file deletion you see on OS X and Linux, but it does mean that third party applications cannot talk to Xojo apps via IPC on Windows. It’d be nice to switch to named pipes, but as far as I know, there’s been no Feedback request for it.
  • The framework attempts to normalize error codes, so that you see errors like 105 AddressInUseError instead of the actual underlying error (EADDRINUSE, in this case). By nature, normalization can lose information about the error.
  • Non-normalized error values can differ across systems. On OS X and Linux, you can end up seeing actual errno codes in some cases. Even these error codes are not standardized across systems and if you were programming in C, you would just use the symbolic names from <errno.h>. For example, ENAMETOOLONG's integer value is 63 on OS X and something different on Linux.
  • On the topic of error codes, not all error codes even come from the BSD socket APIs. Since there is no second property specifying exactly what sort of error code you have, it’s a less than ideal setup.

If you have any other questions, feel free to ask.