]>
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"
20 #include <wx/wxprec.h>
25 #include "wx/socket.h"
26 #include "wx/sckipc.h"
32 #if !USE_SHARED_LIBRARY
33 IMPLEMENT_DYNAMIC_CLASS(wxTCPServer
, wxServerBase
)
34 IMPLEMENT_DYNAMIC_CLASS(wxTCPClient
, wxClientBase
)
35 IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection
, wxConnectionBase
)
38 // It seems to be already defined somewhere in the Xt includes.
56 void Server_OnRequest(wxSocketServer
& server
,
57 wxSocketBase::wxRequestEvent evt
,
59 void Client_OnRequest(wxSocketBase
& sock
,
60 wxSocketBase::wxRequestEvent evt
,
63 // ---------------------------------------------------------------------------
65 // ---------------------------------------------------------------------------
67 wxTCPClient::wxTCPClient (void)
72 wxTCPClient::~wxTCPClient (void)
76 bool wxTCPClient::ValidHost(const wxString
& host
)
80 return addr
.Hostname(host
);
83 wxConnectionBase
*wxTCPClient::MakeConnection (const wxString
& host
,
84 const wxString
& server_name
,
85 const wxString
& topic
)
88 wxSocketHandler
*hsock
= &wxSocketHandler::Master();
89 wxSocketClient
*client
= hsock
->CreateClient();
90 wxSocketStream
*stream
= new wxSocketStream(*client
);
91 wxDataStream
data_s(*stream
);
93 client
->SetNotify(wxSocketBase::REQ_READ
| wxSocketBase::REQ_LOST
);
94 addr
.Service(server_name
);
97 if (!client
->Connect(addr
)) {
101 client
->Notify(FALSE
);
103 // Send topic name, and enquire whether this has succeeded
106 data_s
.Write8(IPC_CONNECT
);
107 data_s
.WriteString(topic
);
109 msg
= data_s
.Read8();
112 if (msg
== IPC_CONNECT
) {
113 wxTCPConnection
*connection
= (wxTCPConnection
*)OnMakeConnection ();
115 if (!connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) {
119 connection
->m_topic
= topic
;
120 client
->Callback(Client_OnRequest
);
121 client
->CallbackData((char *)connection
);
122 client
->Notify(TRUE
);
135 wxConnectionBase
*wxTCPClient::OnMakeConnection()
137 return new wxTCPConnection
;
140 // ---------------------------------------------------------------------------
142 // ---------------------------------------------------------------------------
144 wxTCPServer::wxTCPServer (void)
149 bool wxTCPServer::Create(const wxString
& server_name
)
152 wxSocketHandler
*hsock
= &wxSocketHandler::Master();
153 wxSocketServer
*server
;
155 addr
.Service(server_name
);
157 // Create a socket listening on specified port
158 server
= hsock
->CreateServer(addr
);
159 server
->Callback((wxSocketBase::wxSockCbk
)Server_OnRequest
);
160 server
->SetNotify(wxSocketBase::REQ_ACCEPT
);
162 server
->CallbackData((char *)this);
167 wxTCPServer::~wxTCPServer (void)
171 wxConnectionBase
*wxTCPServer::OnAcceptConnection(const wxString
& topic
)
173 return new wxTCPConnection();
176 // ---------------------------------------------------------------------------
178 // ---------------------------------------------------------------------------
180 wxTCPConnection::wxTCPConnection (void)
181 : wxConnectionBase(),
182 m_sock(NULL
), m_sockstrm(NULL
), m_codec(NULL
)
186 wxTCPConnection::~wxTCPConnection (void)
190 wxDELETE(m_sockstrm
);
193 void wxTCPConnection::Compress(bool on
)
198 // Calls that CLIENT can make.
199 bool wxTCPConnection::Disconnect (void)
201 // Send the the disconnect message to the peer.
202 m_codec
->Write8(IPC_DISCONNECT
);
208 bool wxTCPConnection::Execute (char *data
, int size
, wxDataFormat format
)
210 if (!m_sock
->IsConnected())
213 // Prepare EXECUTE message
214 m_codec
->Write8(IPC_EXECUTE
);
215 m_codec
->Write8(format
);
217 m_codec
->WriteString(data
);
219 m_codec
->Write32(size
);
220 m_codec
->Write(data
, size
);
226 char *wxTCPConnection::Request (const wxString
& item
, int *size
, wxDataFormat format
)
228 if (!m_sock
->IsConnected())
231 m_codec
->Write8(IPC_REQUEST
);
232 m_codec
->WriteString(item
);
233 m_codec
->Write8(format
);
235 // If Unpack doesn't initialize it.
238 ret
= m_codec
->Read8();
245 s
= m_codec
->Read32();
247 m_codec
->Read(data
, s
);
255 bool wxTCPConnection::Poke (const wxString
& item
, char *data
, int size
, wxDataFormat format
)
257 if (!m_sock
->IsConnected())
260 m_codec
->Write8(IPC_POKE
);
261 m_codec
->WriteString(item
);
262 m_codec
->Write8(format
);
264 m_codec
->WriteString(data
);
266 m_codec
->Write32(size
);
267 m_codec
->Write(data
, size
);
273 bool wxTCPConnection::StartAdvise (const wxString
& item
)
277 if (!m_sock
->IsConnected())
280 m_codec
->Write8(IPC_ADVISE_START
);
281 m_codec
->WriteString(item
);
283 ret
= m_codec
->Read8();
291 bool wxTCPConnection::StopAdvise (const wxString
& item
)
295 if (!m_sock
->IsConnected())
298 m_codec
->Write8(IPC_ADVISE_STOP
);
299 m_codec
->WriteString(item
);
301 msg
= m_codec
->Read8();
309 // Calls that SERVER can make
310 bool wxTCPConnection::Advise (const wxString
& item
,
311 char *data
, int size
, wxDataFormat format
)
313 if (!m_sock
->IsConnected())
316 m_codec
->Write8(IPC_ADVISE
);
317 m_codec
->WriteString(item
);
318 m_codec
->Write8(format
);
320 m_codec
->WriteString(data
);
322 m_codec
->Write32(size
);
323 m_codec
->Write(data
, size
);
329 void Client_OnRequest(wxSocketBase
& sock
, wxSocketBase::wxRequestEvent evt
,
333 wxTCPConnection
*connection
= (wxTCPConnection
*)cdata
;
335 wxString topic_name
= connection
->m_topic
;
338 // The socket handler signals us that we lost the connection: destroy all.
339 if (evt
== wxSocketBase::EVT_LOST
) {
341 connection
->OnDisconnect();
345 // Receive message number.
346 codec
= connection
->m_codec
;
347 msg
= codec
->Read8();
355 format
= (wxDataFormat
)codec
->Read8();
356 size
= codec
->Read32();
357 data
= new char[size
];
358 codec
->Read(data
, size
);
360 connection
->OnExecute (topic_name
, data
, size
, format
);
370 item
= codec
->ReadString();
371 format
= (wxDataFormat
)codec
->Read8();
372 size
= codec
->Read32();
373 data
= new char[size
];
374 codec
->Read(data
, size
);
376 connection
->OnAdvise (topic_name
, item
, data
, size
, format
);
381 case IPC_ADVISE_START
: {
382 item
= codec
->ReadString();
384 bool ok
= connection
->OnStartAdvise (topic_name
, item
);
386 codec
->Write8(IPC_ADVISE_START
);
388 codec
->Write8(IPC_FAIL
);
392 case IPC_ADVISE_STOP
: {
393 item
= codec
->ReadString();
395 bool ok
= connection
->OnStopAdvise (topic_name
, item
);
397 codec
->Write8(IPC_ADVISE_STOP
);
399 codec
->Write8(IPC_FAIL
);
408 item
= codec
->ReadString();
409 format
= (wxDataFormat
)codec
->Read8();
410 size
= codec
->Read32();
411 data
= new char[size
];
412 codec
->Read(data
, size
);
414 connection
->OnPoke (topic_name
, item
, data
, size
, format
);
423 item
= codec
->ReadString();
424 format
= (wxDataFormat
)codec
->Read8();
427 char *user_data
= connection
->OnRequest (topic_name
, item
, &user_size
, format
);
430 codec
->Write8(IPC_REQUEST_REPLY
);
431 if (user_size
!= -1) {
432 codec
->Write32(user_size
);
433 codec
->Write(user_data
, user_size
);
435 codec
->WriteString(user_data
);
437 codec
->Write8(IPC_FAIL
);
441 case IPC_DISCONNECT
: {
443 connection
->OnDisconnect();
447 codec
->Write8(IPC_FAIL
);
452 void Server_OnRequest(wxSocketServer
& server
,
453 wxSocketBase::wxRequestEvent evt
, char *cdata
)
455 wxTCPServer
*ipcserv
= (wxTCPServer
*)cdata
;
456 wxSocketStream
*stream
;
459 if (evt
!= wxSocketBase::EVT_ACCEPT
)
462 /* Accept the connection, getting a new socket */
463 wxSocketBase
*sock
= server
.Accept();
465 sock
->SetNotify(wxSocketBase::REQ_READ
| wxSocketBase::REQ_LOST
);
467 stream
= new wxSocketStream(*sock
);
468 codec
= new wxDataStream(*stream
);
474 msg
= codec
->Read8();
476 if (msg
== IPC_CONNECT
) {
478 topic_name
= codec
->ReadString();
480 /* Register new socket with the notifier */
481 wxTCPConnection
*new_connection
=
482 (wxTCPConnection
*)ipcserv
->OnAcceptConnection (topic_name
);
483 if (new_connection
) {
484 if (!new_connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) {
485 delete new_connection
;
486 codec
->Write8(IPC_FAIL
);
489 // Acknowledge success
490 codec
->Write8(IPC_CONNECT
);
492 new_connection
->m_topic
= topic_name
;
493 new_connection
->m_sockstrm
= stream
;
494 new_connection
->m_codec
= codec
;
495 sock
->Callback(Client_OnRequest
);
496 sock
->CallbackData((char *)new_connection
);
499 // Send failure message
500 codec
->Write8(IPC_FAIL
);