Socket Comm Sequence Issue
Alex Tweedly
alex at tweedly.net
Fri Apr 15 21:09:20 EDT 2005
Ken Ray wrote:
>I'm trying to get two apps to talk to each other over sockets on OS X, which
>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:
>
>
There have now been lots of replies with specific suggestions -
hopefully Ken's now moving forward with his specific problem.
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
More information about the use-livecode
mailing list