]>
git.saurik.com Git - wxWidgets.git/blob - src/common/sckipc.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Interprocess communication implementation (wxSocket version)
4 // Author: Julian Smart, Guilhem Lavaux
5 // Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
8 // Copyright: (c) Julian Smart 1993, Guilhem Lavaux 1997, 1998
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "sckipc.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 #include "wx/socket.h"
30 #include "wx/sckipc.h"
36 #if !USE_SHARED_LIBRARY
37 IMPLEMENT_DYNAMIC_CLASS(wxTCPServer
, wxServerBase
)
38 IMPLEMENT_DYNAMIC_CLASS(wxTCPClient
, wxClientBase
)
39 IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection
, wxConnectionBase
)
42 // It seems to be already defined somewhere in the Xt includes.
60 void Server_OnRequest(wxSocketServer
& server
,
61 wxSocketBase::wxRequestEvent evt
,
63 void Client_OnRequest(wxSocketBase
& sock
,
64 wxSocketBase::wxRequestEvent evt
,
67 // ---------------------------------------------------------------------------
69 // ---------------------------------------------------------------------------
71 wxTCPClient::wxTCPClient (void)
76 wxTCPClient::~wxTCPClient (void)
80 bool wxTCPClient::ValidHost(const wxString
& host
)
84 return addr
.Hostname(host
);
87 wxConnectionBase
*wxTCPClient::MakeConnection (const wxString
& host
,
88 const wxString
& server_name
,
89 const wxString
& topic
)
92 wxSocketHandler
*hsock
= &wxSocketHandler::Master();
93 wxSocketClient
*client
= hsock
->CreateClient();
94 wxSocketStream
*stream
= new wxSocketStream(*client
);
95 wxDataStream
data_s(*stream
);
97 client
->SetNotify(wxSocketBase::REQ_READ
| wxSocketBase::REQ_LOST
);
98 addr
.Service(server_name
);
101 if (!client
->Connect(addr
)) {
105 client
->Notify(FALSE
);
107 // Send topic name, and enquire whether this has succeeded
110 data_s
.Write8(IPC_CONNECT
);
111 data_s
.WriteString(topic
);
113 msg
= data_s
.Read8();
116 if (msg
== IPC_CONNECT
) {
117 wxTCPConnection
*connection
= (wxTCPConnection
*)OnMakeConnection ();
119 if (!connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) {
123 connection
->m_topic
= topic
;
124 client
->Callback(Client_OnRequest
);
125 client
->CallbackData((char *)connection
);
126 client
->Notify(TRUE
);
139 wxConnectionBase
*wxTCPClient::OnMakeConnection()
141 return new wxTCPConnection
;
144 // ---------------------------------------------------------------------------
146 // ---------------------------------------------------------------------------
148 wxTCPServer::wxTCPServer (void)
153 bool wxTCPServer::Create(const wxString
& server_name
)
156 wxSocketHandler
*hsock
= &wxSocketHandler::Master();
157 wxSocketServer
*server
;
159 addr
.Service(server_name
);
161 // Create a socket listening on specified port
162 server
= hsock
->CreateServer(addr
);
163 server
->Callback((wxSocketBase::wxSockCbk
)Server_OnRequest
);
164 server
->SetNotify(wxSocketBase::REQ_ACCEPT
);
166 server
->CallbackData((char *)this);
171 wxTCPServer::~wxTCPServer(void)
175 wxConnectionBase
*wxTCPServer::OnAcceptConnection( const wxString
& WXUNUSED(topic
) )
177 return new wxTCPConnection();
180 // ---------------------------------------------------------------------------
182 // ---------------------------------------------------------------------------
184 wxTCPConnection::wxTCPConnection (void)
185 : wxConnectionBase(),
186 m_sock(NULL
), m_sockstrm(NULL
), m_codec(NULL
)
190 wxTCPConnection::~wxTCPConnection (void)
194 wxDELETE(m_sockstrm
);
197 void wxTCPConnection::Compress(bool WXUNUSED(on
))
202 // Calls that CLIENT can make.
203 bool wxTCPConnection::Disconnect (void)
205 // Send the the disconnect message to the peer.
206 m_codec
->Write8(IPC_DISCONNECT
);
212 bool wxTCPConnection::Execute (char *data
, int size
, wxDataFormat format
)
214 if (!m_sock
->IsConnected())
217 // Prepare EXECUTE message
218 m_codec
->Write8(IPC_EXECUTE
);
219 m_codec
->Write8(format
);
221 m_codec
->WriteString(data
);
223 m_codec
->Write32(size
);
224 m_codec
->Write(data
, size
);
230 char *wxTCPConnection::Request (const wxString
& item
, int *size
, wxDataFormat format
)
232 if (!m_sock
->IsConnected())
235 m_codec
->Write8(IPC_REQUEST
);
236 m_codec
->WriteString(item
);
237 m_codec
->Write8(format
);
239 // If Unpack doesn't initialize it.
242 ret
= m_codec
->Read8();
249 s
= m_codec
->Read32();
251 m_codec
->Read(data
, s
);
259 bool wxTCPConnection::Poke (const wxString
& item
, char *data
, int size
, wxDataFormat format
)
261 if (!m_sock
->IsConnected())
264 m_codec
->Write8(IPC_POKE
);
265 m_codec
->WriteString(item
);
266 m_codec
->Write8(format
);
268 m_codec
->WriteString(data
);
270 m_codec
->Write32(size
);
271 m_codec
->Write(data
, size
);
277 bool wxTCPConnection::StartAdvise (const wxString
& item
)
281 if (!m_sock
->IsConnected())
284 m_codec
->Write8(IPC_ADVISE_START
);
285 m_codec
->WriteString(item
);
287 ret
= m_codec
->Read8();
295 bool wxTCPConnection::StopAdvise (const wxString
& item
)
299 if (!m_sock
->IsConnected())
302 m_codec
->Write8(IPC_ADVISE_STOP
);
303 m_codec
->WriteString(item
);
305 msg
= m_codec
->Read8();
313 // Calls that SERVER can make
314 bool wxTCPConnection::Advise (const wxString
& item
,
315 char *data
, int size
, wxDataFormat format
)
317 if (!m_sock
->IsConnected())
320 m_codec
->Write8(IPC_ADVISE
);
321 m_codec
->WriteString(item
);
322 m_codec
->Write8(format
);
324 m_codec
->WriteString(data
);
326 m_codec
->Write32(size
);
327 m_codec
->Write(data
, size
);
333 void Client_OnRequest(wxSocketBase
& sock
, wxSocketBase::wxRequestEvent evt
,
337 wxTCPConnection
*connection
= (wxTCPConnection
*)cdata
;
339 wxString topic_name
= connection
->m_topic
;
342 // The socket handler signals us that we lost the connection: destroy all.
343 if (evt
== wxSocketBase::EVT_LOST
) {
345 connection
->OnDisconnect();
349 // Receive message number.
350 codec
= connection
->m_codec
;
351 msg
= codec
->Read8();
359 format
= (wxDataFormat
)codec
->Read8();
360 size
= codec
->Read32();
361 data
= new char[size
];
362 codec
->Read(data
, size
);
364 connection
->OnExecute (topic_name
, data
, size
, format
);
374 item
= codec
->ReadString();
375 format
= (wxDataFormat
)codec
->Read8();
376 size
= codec
->Read32();
377 data
= new char[size
];
378 codec
->Read(data
, size
);
380 connection
->OnAdvise (topic_name
, item
, data
, size
, format
);
385 case IPC_ADVISE_START
: {
386 item
= codec
->ReadString();
388 bool ok
= connection
->OnStartAdvise (topic_name
, item
);
390 codec
->Write8(IPC_ADVISE_START
);
392 codec
->Write8(IPC_FAIL
);
396 case IPC_ADVISE_STOP
: {
397 item
= codec
->ReadString();
399 bool ok
= connection
->OnStopAdvise (topic_name
, item
);
401 codec
->Write8(IPC_ADVISE_STOP
);
403 codec
->Write8(IPC_FAIL
);
412 item
= codec
->ReadString();
413 format
= (wxDataFormat
)codec
->Read8();
414 size
= codec
->Read32();
415 data
= new char[size
];
416 codec
->Read(data
, size
);
418 connection
->OnPoke (topic_name
, item
, data
, size
, format
);
427 item
= codec
->ReadString();
428 format
= (wxDataFormat
)codec
->Read8();
431 char *user_data
= connection
->OnRequest (topic_name
, item
, &user_size
, format
);
434 codec
->Write8(IPC_REQUEST_REPLY
);
435 if (user_size
!= -1) {
436 codec
->Write32(user_size
);
437 codec
->Write(user_data
, user_size
);
439 codec
->WriteString(user_data
);
441 codec
->Write8(IPC_FAIL
);
445 case IPC_DISCONNECT
: {
447 connection
->OnDisconnect();
451 codec
->Write8(IPC_FAIL
);
456 void Server_OnRequest(wxSocketServer
& server
,
457 wxSocketBase::wxRequestEvent evt
, char *cdata
)
459 wxTCPServer
*ipcserv
= (wxTCPServer
*)cdata
;
460 wxSocketStream
*stream
;
463 if (evt
!= wxSocketBase::EVT_ACCEPT
)
466 /* Accept the connection, getting a new socket */
467 wxSocketBase
*sock
= server
.Accept();
469 sock
->SetNotify(wxSocketBase::REQ_READ
| wxSocketBase::REQ_LOST
);
471 stream
= new wxSocketStream(*sock
);
472 codec
= new wxDataStream(*stream
);
478 msg
= codec
->Read8();
480 if (msg
== IPC_CONNECT
) {
482 topic_name
= codec
->ReadString();
484 /* Register new socket with the notifier */
485 wxTCPConnection
*new_connection
=
486 (wxTCPConnection
*)ipcserv
->OnAcceptConnection (topic_name
);
487 if (new_connection
) {
488 if (!new_connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) {
489 delete new_connection
;
490 codec
->Write8(IPC_FAIL
);
493 // Acknowledge success
494 codec
->Write8(IPC_CONNECT
);
496 new_connection
->m_topic
= topic_name
;
497 new_connection
->m_sockstrm
= stream
;
498 new_connection
->m_codec
= codec
;
499 sock
->Callback(Client_OnRequest
);
500 sock
->CallbackData((char *)new_connection
);
503 // Send failure message
504 codec
->Write8(IPC_FAIL
);