Ken Ray wrote:
I'm trying to get two apps to talk to each other over sockets on OS X, whichThere have now been lots of replies with specific suggestions - hopefully Ken's now moving forward with his specific problem.
means that both apps need to be in "listening" mode as well as "speaking"
mode. The relevant code I'm using for testing this right now is shown below,
and doesn't trap for errors or messages that I'm not interested in:
I thought I'd step back and try to characterize the solution space for "peer" apps in a (relatively) general way.
There are 3 main approaches to this problem, listed below in increasing order of generality and complexity.
1. Asymmetry
Although the two apps need to be in both listening and speaking mode, that often doesn't require that both apps be in both modes for the purpose of creating a socket connection. Often, it is enough that either app can initiate exchanges over an already open socket.
Advantages: - simplest - only uses up one fixed socket number - only ever opens one connection Disadvantages - needs one socket open all the time both apps are running
Arbitrarily choose one of the two apps, and declare it to be the "listener". As soon as it starts up, it listens ("accept connection on socket N"). If it receives an incoming connection, it remembers the socket passed in the "accept" callback message. When it wishes to talk to the other app, it uses the socket remembered; if no socket has arrived via the accept callback, then the other app is unavailable.
The "other" app is declared to be the "speaker"; as soon as it starts up, it tries to open a socket to the other app. If this fails, it sets a timer and retries; it must continue to retry periodically (tenaciously). If the socket is ever closed (either a socketerror, or socketclosed, or because this app is restarted), it must try to re-open the socket, and keep trying to do so.
Once the connection is open, either side can start an exchange of data.
This method CAN be used for the case where the "two apps" are actually different instances of the same application - but great care must be taken to handle the race condition where both instances time out (almost) simultaneously.
An example of this case is in the "TCP App 1" and "TCP App 2" examples on RevOnline (though they skip the "tenacious retry" on opening a socket).
2.Crossed (paired, scissor) connections
Each app uses a different socket, listens on one of them and connects on the other as needed.
By convention, two adjacent numbered sockets are used - but there is NO meaning at all to the fact that they are adjacent numbers - it's only a convention, and it's only there to make it easier for people to remember and handle.
app1 starts up, listens on a socket (e.g. 60000) and when it wants to speak to the other app, attempts to connect to the "other" socket (e.g. 59999). app2 does the same, except listens on 59999 and connects to 60000.
Advantages:
- either app can open a socket, conduct an exchange and close the socket again
- no need to keep a connection open continuously
Disadvantages:
- uses two numbered sockets
- doesn't extend well to multiple apps
- can have two connections open
There are many small variants within this overall approach. The most significant one is whether and how the two connections are used.
The simplest approach is that each app is allowed to go ahead and open the connection to the other app; all data (including "replies") it wishes to send to the other app go over the connection it opened. Thus we have two (bidirectional) connections open,but each is being used in only one direction.
A (usually) better approach is that once one of the connections is successfully opened, it (and the return socket discovered during the "accept" callback, are used. The second numbered connection never needs be opened (or if it is, can be closed again).
A third method is for each connection to be opened when the app wishes to initiate a transaction - and that transaction is conducted over the connection opened for it, and the return socket discovered during the "accept". This is more complex, and has the cost of using both sockets bidirectionally. But it can have significant benefits in logging, testing and debugging simplicity, since each transaction can be observed independent of any simultaneous transaction initiated by the other side.
An example of this (first variant) is in the "TCP App 3" and "TCP App 4" samples on RevOnline.
3.Symmetrical server mode.
This is the easiest to say, but the hardest to do :-)
Each app listens on the port; if the port is already in use, it chooses another one (by convention, the next higher numbered one), simply complains with an error. When the app wants to speak to another app, it tries to open a connection to it (and if that fails it may retry, or may try to open next higher numbered port(s) - app dependent).
This is usually only done if there can be multiple apps that need to talk freely but intermittently with any of the other apps (and hence the paired socket numbers won't work), or for multiple instances of the same app, where there is no option to have each instance know a different port number ahead of time). If each app (or each instance of the app) is on a different machine, this all works fairly smoothly; but if there are, or can be, multiple instances on the same machine, this can get very tricky.
Advantages: - most general - multiple (more than 2) apps can be handled Disadvantages: - complex - difficult to text and debug - complex - restrictions on multiple apps on same machine - complex
Although it can become complex, if the suitable constraints can be put in place (e.g. if the port is in use when you try to listen on it, that is an unrecoverable error) the complexity can be kept under control. Many traditional servers fall into this category (e.g. web server, etc.).
If these "suitable constraints" cannot be assumed, this is particularly difficult to do Rev, and probably shouldn't be tried unless you have gathered a lot of experience in this area.
No example of this yet.
-- Alex Tweedly http://www.tweedly.net
-- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.308 / Virus Database: 266.9.7 - Release Date: 12/04/2005
_______________________________________________ use-revolution mailing list [email protected] http://lists.runrev.com/mailman/listinfo/use-revolution
