]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{Interprocess communication overview}\label{ipcoverview} |
2 | ||
f010ad48 JS |
3 | Classes: \helpref{wxServer}{wxddeserver}, |
4 | \helpref{wxConnection}{wxddeconnection}, | |
5 | \helpref{wxClient}{wxddeclient} | |
6 | %\helpref{wxTCPServer}{wxtcpserver}, \helpref{wxTCPConnection}{wxtcpconnection}, | |
7 | %\helpref{wxTCPClient}{wxtcpclient} | |
a660d684 | 8 | |
fc2171bd | 9 | wxWidgets has a number of different classes to help with |
f010ad48 JS |
10 | interprocess communication and network programming. This section |
11 | only discusses one family of classes -- the DDE-like protocol -- | |
12 | but here's a list of other useful classes: | |
a660d684 | 13 | |
e2a6f233 | 14 | \begin{itemize}\itemsep=0pt |
f010ad48 JS |
15 | \item \helpref{wxSocketEvent}{wxsocketevent}, |
16 | \helpref{wxSocketBase}{wxsocketbase}, | |
17 | \helpref{wxSocketClient}{wxsocketclient}, | |
e2a6f233 | 18 | \helpref{wxSocketServer}{wxsocketserver}: classes for the low-level TCP/IP API. |
f010ad48 | 19 | \item \helpref{wxProtocol}{wxprotocol}, \helpref{wxURL}{wxurl}, \helpref{wxFTP}{wxftp}, \helpref{wxHTTP}{wxhttp}: classes |
e2a6f233 JS |
20 | for programming popular Internet protocols. |
21 | \end{itemize} | |
22 | ||
fc2171bd | 23 | wxWidgets' DDE-like protocol is a high-level protocol based on |
f010ad48 JS |
24 | Windows DDE. There are two implementations of this DDE-like |
25 | protocol: one using real DDE running on Windows only, and another | |
26 | using TCP/IP (sockets) that runs on most platforms. Since the API | |
27 | and virtually all of the behaviour is the same apart from the | |
28 | names of the classes, you should find it easy to switch between | |
29 | the two implementations. | |
e2a6f233 | 30 | |
f010ad48 JS |
31 | Notice that by including {\tt <wx/ipc.h>} you may define |
32 | convenient synonyms for the IPC classes: {\tt wxServer} for either | |
33 | {\tt wxDDEServer} or {\tt wxTCPServer} depending on whether | |
34 | DDE-based or socket-based implementation is used and the same | |
35 | thing for {\tt wxClient} and {\tt wxConnection}. | |
d5172a58 | 36 | |
f70c0443 WS |
37 | By default, the DDE implementation is used under Windows. DDE works |
38 | within one computer only. If you want to use IPC between | |
f010ad48 JS |
39 | different workstations you should define {\tt |
40 | wxUSE\_DDE\_FOR\_IPC} as $0$ before including this header -- this | |
41 | will force using TCP/IP implementation even under Windows. | |
d5172a58 | 42 | |
f010ad48 JS |
43 | The following description refers to wx... but remember that the |
44 | equivalent wxTCP... and wxDDE... classes can be used in much the | |
45 | same way. | |
e2a6f233 | 46 | |
f010ad48 | 47 | Three classes are central to the DDE-like API: |
a660d684 KB |
48 | |
49 | \begin{enumerate}\itemsep=0pt | |
f010ad48 | 50 | \item wxClient. This represents the client application, and is used |
a660d684 | 51 | only within a client program. |
f010ad48 | 52 | \item wxServer. This represents the server application, and is used |
a660d684 | 53 | only within a server program. |
f010ad48 JS |
54 | \item wxConnection. This represents the connection from the |
55 | client to the server - both the client and the server use an | |
56 | instance of this class, one per connection. Most DDE transactions | |
57 | operate on this object. | |
a660d684 KB |
58 | \end{enumerate} |
59 | ||
f010ad48 JS |
60 | Messages between applications are usually identified by three |
61 | variables: connection object, topic name and item name. A data | |
62 | string is a fourth element of some messages. To create a | |
63 | connection (a conversation in Windows parlance), the client | |
64 | application uses wxClient::MakeConnection to send a message to the | |
65 | server object, with a string service name to identify the server | |
66 | and a topic name to identify the topic for the duration of the | |
67 | connection. Under Unix, the service name may be either an integer | |
68 | port identifier in which case an Internet domain socket will be | |
69 | used for the communications or a valid file name (which shouldn't | |
70 | exist and will be deleted afterwards) in which case a Unix domain | |
71 | socket is created. | |
0dbfd66d | 72 | |
f70c0443 | 73 | {\bf SECURITY NOTE:} Using Internet domain sockets is extremely insecure for |
0dbfd66d VZ |
74 | IPC as there is absolutely no access control for them, use Unix domain sockets |
75 | whenever possible! | |
a660d684 | 76 | |
f010ad48 JS |
77 | The server then responds and either vetoes the connection or |
78 | allows it. If allowed, both the server and client objects create | |
79 | wxConnection objects which persist until the connection is | |
80 | closed. The connection object is then used for sending and | |
81 | receiving subsequent messages between client and server - | |
82 | overriding virtual functions in your class derived from | |
83 | wxConnection allows you to handle the DDE messages. | |
a660d684 KB |
84 | |
85 | To create a working server, the programmer must: | |
86 | ||
87 | \begin{enumerate}\itemsep=0pt | |
f010ad48 JS |
88 | \item Derive a class from wxConnection, providing handlers for various messages sent to the server |
89 | side of a wxConnection (e.g. OnExecute, OnRequest, OnPoke). Only | |
90 | the handlers actually required by the application need to be | |
91 | overridden. | |
92 | \item Derive a class from wxServer, overriding OnAcceptConnection | |
93 | to accept or reject a connection on the basis of the topic | |
94 | argument. This member must create and return an instance of the | |
95 | derived connection class if the connection is accepted. | |
96 | \item Create an instance of your server object and call Create to | |
a660d684 | 97 | activate it, giving it a service name. |
a660d684 KB |
98 | \end{enumerate} |
99 | ||
100 | To create a working client, the programmer must: | |
101 | ||
102 | \begin{enumerate}\itemsep=0pt | |
f010ad48 JS |
103 | \item Derive a class from wxConnection, providing handlers for various |
104 | messages sent to the client side of a wxConnection (e.g. | |
105 | OnAdvise). Only the handlers actually required by the application | |
106 | need to be overridden. | |
107 | \item Derive a class from wxClient, overriding OnMakeConnection to | |
108 | create and return an instance of the derived connection class. | |
a660d684 | 109 | \item Create an instance of your client object. |
f010ad48 JS |
110 | \item When appropriate, create a new connection using |
111 | \helpref{wxClient::MakeConnection}{wxddeclientmakeconnection}, | |
112 | with arguments host name (processed in Unix only, use `localhost' | |
113 | for local computer), service name, and topic name for this | |
114 | connection. The client object will call | |
115 | \helpref{OnMakeConnection}{wxddeclientonmakeconnection} to create | |
116 | a connection object of the derived class if the connection is | |
117 | successful. | |
118 | \item Use the wxConnection member functions to send messages to the server. | |
a660d684 KB |
119 | \end{enumerate} |
120 | ||
121 | \subsection{Data transfer} | |
122 | ||
f010ad48 JS |
123 | These are the ways that data can be transferred from one |
124 | application to another. These are methods of wxConnection. | |
a660d684 KB |
125 | |
126 | \begin{itemize}\itemsep=0pt | |
127 | \item {\bf Execute:} the client calls the server with a data string representing | |
128 | a command to be executed. This succeeds or fails, depending on the | |
129 | server's willingness to answer. If the client wants to find the result | |
130 | of the Execute command other than success or failure, it has to explicitly | |
131 | call Request. | |
132 | \item {\bf Request:} the client asks the server for a particular data string | |
133 | associated with a given item string. If the server is unwilling to | |
134 | reply, the return value is NULL. Otherwise, the return value is a string | |
135 | (actually a pointer to the connection buffer, so it should not be | |
136 | deallocated by the application). | |
137 | \item {\bf Poke:} The client sends a data string associated with an item | |
138 | string directly to the server. This succeeds or fails. | |
139 | \item {\bf Advise:} The client asks to be advised of any change in data | |
140 | associated with a particular item. If the server agrees, the server will | |
141 | send an OnAdvise message to the client along with the item and data. | |
142 | \end{itemize} | |
143 | ||
144 | The default data type is wxCF\_TEXT (ASCII text), and the default data | |
145 | size is the length of the null-terminated string. Windows-specific data | |
146 | types could also be used on the PC. | |
147 | ||
148 | \subsection{Examples} | |
149 | ||
150 | See the sample programs {\it server}\/ and {\it client}\/ in the IPC | |
151 | samples directory. Run the server, then the client. This demonstrates | |
152 | using the Execute, Request, and Poke commands from the client, together | |
153 | with an Advise loop: selecting an item in the server list box causes | |
154 | that item to be highlighted in the client list box. | |
155 | ||
a660d684 KB |
156 | \subsection{More DDE details} |
157 | ||
f010ad48 JS |
158 | A wxClient object initiates the client part of a client-server |
159 | DDE-like (Dynamic Data Exchange) conversation (available in both | |
e2a6f233 | 160 | Windows and Unix). |
a660d684 KB |
161 | |
162 | To create a client which can communicate with a suitable server, | |
f010ad48 JS |
163 | you need to derive a class from wxConnection and another from |
164 | wxClient. The custom wxConnection class will receive | |
165 | communications in a `conversation' with a server. and the custom | |
166 | wxServer is required so that a user-overridden | |
167 | \helpref{wxDDEClient::OnMakeConnection}{wxddeclientonmakeconnection} | |
168 | member can return a wxDDEConnection of the required class, when a | |
169 | connection is made. | |
a660d684 KB |
170 | |
171 | For example: | |
172 | ||
173 | \begin{verbatim} | |
f010ad48 | 174 | class MyConnection: public wxConnection { |
a660d684 | 175 | public: |
f010ad48 | 176 | MyConnection(void)::wxConnection() {} |
a660d684 | 177 | ~MyConnection(void) { } |
e2a6f233 | 178 | bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) |
a660d684 KB |
179 | { wxMessageBox(topic, data); } |
180 | }; | |
181 | ||
f010ad48 | 182 | class MyClient: public wxClient { |
a660d684 KB |
183 | public: |
184 | MyClient(void) {} | |
e2a6f233 | 185 | wxConnectionBase *OnMakeConnection(void) { return new MyConnection; } |
a660d684 KB |
186 | }; |
187 | ||
188 | \end{verbatim} | |
189 | ||
f010ad48 JS |
190 | Here, {\bf MyConnection} will respond to |
191 | \helpref{OnAdvise}{wxddeconnectiononadvise} messages sent by the | |
192 | server by displaying a message box. | |
193 | ||
194 | When the client application starts, it must create an instance of | |
195 | the derived wxClient. In the following, command line arguments | |
196 | are used to pass the host name (the name of the machine the | |
197 | server is running on) and the server name (identifying the server | |
198 | process). Calling | |
199 | \helpref{wxDDEClient::MakeConnection}{wxddeclientmakeconnection}\rtfsp | |
200 | implicitly creates an instance of {\bf MyConnection} if the | |
201 | request for a connection is accepted, and the client then | |
202 | requests an {\it Advise} loop from the server (an Advise loop is | |
203 | where the server calls the client when data has changed). | |
a660d684 KB |
204 | |
205 | \begin{verbatim} | |
e2a6f233 JS |
206 | wxString server = "4242"; |
207 | wxString hostName; | |
208 | wxGetHostName(hostName); | |
a660d684 KB |
209 | |
210 | // Create a new client | |
211 | MyClient *client = new MyClient; | |
e2a6f233 | 212 | connection = (MyConnection *)client->MakeConnection(hostName, server, "IPC TEST"); |
a660d684 | 213 | |
e2a6f233 | 214 | if (!connection) |
a660d684 KB |
215 | { |
216 | wxMessageBox("Failed to make connection to server", "Client Demo Error"); | |
217 | return NULL; | |
218 | } | |
e2a6f233 | 219 | connection->StartAdvise("Item"); |
a660d684 KB |
220 | \end{verbatim} |
221 | ||
e2a6f233 | 222 | Note that it is no longer necessary to call wxDDEInitialize or wxDDECleanUp, since |
f70c0443 | 223 | wxWidgets will do this by itself if necessary. |
a660d684 | 224 |