]>
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" 
  31 #include "wx/socket.h" 
  32 #include "wx/sckipc.h" 
  38 #if !USE_SHARED_LIBRARY 
  39 IMPLEMENT_DYNAMIC_CLASS(wxTCPServer
, wxServerBase
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxTCPClient
, wxClientBase
) 
  41 IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection
, wxConnectionBase
) 
  44 // It seems to be already defined somewhere in the Xt includes. 
  62 void Server_OnRequest(wxSocketServer
& server
, 
  65 void Client_OnRequest(wxSocketBase
& sock
, 
  69 // --------------------------------------------------------------------------- 
  71 // --------------------------------------------------------------------------- 
  73 wxTCPClient::wxTCPClient () 
  78 wxTCPClient::~wxTCPClient () 
  82 bool wxTCPClient::ValidHost(const wxString
& host
) 
  86   return addr
.Hostname(host
); 
  89 wxConnectionBase 
*wxTCPClient::MakeConnection (const wxString
& host
, 
  90                                                const wxString
& server_name
, 
  91                                                const wxString
& topic
) 
  94   wxSocketClient 
*client 
= new wxSocketClient(); 
  95   wxSocketStream 
*stream 
= new wxSocketStream(*client
); 
  96   wxDataInputStream 
data_is(*stream
); 
  97   wxDataOutputStream 
data_os(*stream
); 
  99   client
->SetNotify(wxSOCKET_INPUT_FLAG 
| wxSOCKET_LOST_FLAG
); 
 100   addr
.Service(server_name
); 
 103   if (!client
->Connect(addr
)) { 
 107   client
->Notify(FALSE
); 
 109   // Send topic name, and enquire whether this has succeeded 
 112   data_os
.Write8(IPC_CONNECT
); 
 113   data_os
.WriteString(topic
); 
 115   msg 
= data_is
.Read8(); 
 118   if (msg 
== IPC_CONNECT
) { 
 119     wxTCPConnection 
*connection 
= (wxTCPConnection 
*)OnMakeConnection (); 
 121       if (!connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) { 
 125       connection
->m_topic 
= topic
; 
 126       client
->Callback(Client_OnRequest
); 
 127       client
->CallbackData((char *)connection
); 
 128       client
->Notify(TRUE
); 
 140 wxConnectionBase 
*wxTCPClient::OnMakeConnection() 
 142   return new wxTCPConnection
; 
 145 // --------------------------------------------------------------------------- 
 147 // --------------------------------------------------------------------------- 
 149 wxTCPServer::wxTCPServer () 
 154 bool wxTCPServer::Create(const wxString
& server_name
) 
 157   wxSocketServer 
*server
; 
 159   addr
.Service(server_name
); 
 161   // Create a socket listening on specified port 
 162   server 
= new wxSocketServer(addr
); 
 163   server
->Callback((wxSocketBase::wxSockCbk
)Server_OnRequest
); 
 164   server
->SetNotify(wxSOCKET_CONNECTION_FLAG
); 
 166   server
->CallbackData((char *)this); 
 171 wxTCPServer::~wxTCPServer() 
 175 wxConnectionBase 
*wxTCPServer::OnAcceptConnection( const wxString
& WXUNUSED(topic
) ) 
 177   return new wxTCPConnection(); 
 180 // --------------------------------------------------------------------------- 
 182 // --------------------------------------------------------------------------- 
 184 wxTCPConnection::wxTCPConnection () 
 185   : wxConnectionBase(), 
 186     m_sock(NULL
), m_sockstrm(NULL
), m_codeci(NULL
), m_codeco(NULL
) 
 190 wxTCPConnection::wxTCPConnection(char * WXUNUSED(buffer
), int WXUNUSED(size
)) 
 194 wxTCPConnection::~wxTCPConnection () 
 199   wxDELETE(m_sockstrm
); 
 202 void wxTCPConnection::Compress(bool WXUNUSED(on
)) 
 207 // Calls that CLIENT can make. 
 208 bool wxTCPConnection::Disconnect () 
 210   // Send the the disconnect message to the peer. 
 211   m_codeco
->Write8(IPC_DISCONNECT
); 
 217 bool wxTCPConnection::Execute (const wxChar 
*data
, int size
, wxIPCFormat format
) 
 219   if (!m_sock
->IsConnected()) 
 222   // Prepare EXECUTE message 
 223   m_codeco
->Write8(IPC_EXECUTE
); 
 224   m_codeco
->Write8(format
); 
 226     m_codeco
->WriteString(data
); 
 228     m_codeco
->Write32(size
); 
 229     m_sockstrm
->Write(data
, size
); 
 235 char *wxTCPConnection::Request (const wxString
& item
, int *size
, wxIPCFormat format
) 
 237   if (!m_sock
->IsConnected()) 
 240   m_codeco
->Write8(IPC_REQUEST
); 
 241   m_codeco
->WriteString(item
); 
 242   m_codeco
->Write8(format
); 
 244   // If Unpack doesn't initialize it. 
 247   ret 
= m_codeci
->Read8(); 
 254     s 
= m_codeci
->Read32(); 
 256     m_sockstrm
->Read(data
, s
); 
 264 bool wxTCPConnection::Poke (const wxString
& item
, wxChar 
*data
, int size
, wxIPCFormat format
) 
 266   if (!m_sock
->IsConnected()) 
 269   m_codeco
->Write8(IPC_POKE
); 
 270   m_codeco
->WriteString(item
); 
 271   m_codeco
->Write8(format
); 
 273     m_codeco
->WriteString(data
); 
 275     m_codeco
->Write32(size
); 
 276     m_sockstrm
->Write(data
, size
); 
 282 bool wxTCPConnection::StartAdvise (const wxString
& item
) 
 286   if (!m_sock
->IsConnected()) 
 289   m_codeco
->Write8(IPC_ADVISE_START
); 
 290   m_codeco
->WriteString(item
); 
 292   ret 
= m_codeci
->Read8(); 
 300 bool wxTCPConnection::StopAdvise (const wxString
& item
) 
 304   if (!m_sock
->IsConnected()) 
 307   m_codeco
->Write8(IPC_ADVISE_STOP
); 
 308   m_codeco
->WriteString(item
); 
 310   msg 
= m_codeci
->Read8(); 
 318 // Calls that SERVER can make 
 319 bool wxTCPConnection::Advise (const wxString
& item
, 
 320                               wxChar 
*data
, int size
, wxIPCFormat format
) 
 322   if (!m_sock
->IsConnected()) 
 325   m_codeco
->Write8(IPC_ADVISE
); 
 326   m_codeco
->WriteString(item
); 
 327   m_codeco
->Write8(format
); 
 329     m_codeco
->WriteString(data
); 
 331     m_codeco
->Write32(size
); 
 332     m_sockstrm
->Write(data
, size
); 
 338 void Client_OnRequest(wxSocketBase
& sock
, wxSocketNotify evt
, 
 342   wxTCPConnection 
*connection 
= (wxTCPConnection 
*)cdata
; 
 343   wxDataInputStream 
*codeci
; 
 344   wxDataOutputStream 
*codeco
;  
 345   wxSocketStream 
*sockstrm
; 
 346   wxString topic_name 
= connection
->m_topic
; 
 349   // The socket handler signals us that we lost the connection: destroy all. 
 350   if (evt 
== wxSOCKET_LOST
) { 
 352     connection
->OnDisconnect(); 
 356   // Receive message number. 
 357   codeci 
= connection
->m_codeci
; 
 358   codeco 
= connection
->m_codeco
; 
 359   sockstrm 
= connection
->m_sockstrm
; 
 360   msg 
= codeci
->Read8(); 
 368     format 
= (wxIPCFormat
)codeci
->Read8(); 
 369     size 
= codeci
->Read32(); 
 370     data 
= new char[size
]; 
 371     sockstrm
->Read(data
, size
); 
 373     connection
->OnExecute (topic_name
, data
, size
, format
); 
 383     item 
= codeci
->ReadString(); 
 384     format 
= (wxIPCFormat
)codeci
->Read8(); 
 385     size 
= codeci
->Read32(); 
 386     data 
= new char[size
]; 
 387     sockstrm
->Read(data
, size
); 
 389     connection
->OnAdvise (topic_name
, item
, data
, size
, format
); 
 394   case IPC_ADVISE_START
: { 
 395     item 
= codeci
->ReadString(); 
 397     bool ok 
= connection
->OnStartAdvise (topic_name
, item
); 
 399       codeco
->Write8(IPC_ADVISE_START
); 
 401       codeco
->Write8(IPC_FAIL
); 
 405   case IPC_ADVISE_STOP
: { 
 406     item 
= codeci
->ReadString(); 
 408     bool ok 
= connection
->OnStopAdvise (topic_name
, item
); 
 410       codeco
->Write8(IPC_ADVISE_STOP
); 
 412       codeco
->Write8(IPC_FAIL
); 
 421     item 
= codeci
->ReadString(); 
 422     format 
= (wxIPCFormat
)codeci
->Read8(); 
 423     size 
= codeci
->Read32(); 
 424     data 
= new wxChar
[size
]; 
 425     sockstrm
->Read(data
, size
); 
 427     connection
->OnPoke (topic_name
, item
, data
, size
, format
); 
 436     item 
= codeci
->ReadString(); 
 437     format 
= (wxIPCFormat
)codeci
->Read8(); 
 440     char *user_data 
= connection
->OnRequest (topic_name
, item
, &user_size
, format
); 
 443       codeco
->Write8(IPC_REQUEST_REPLY
); 
 444       if (user_size 
!= -1) { 
 445         codeco
->Write32(user_size
); 
 446         sockstrm
->Write(user_data
, user_size
); 
 448         codeco
->WriteString(user_data
); 
 450       codeco
->Write8(IPC_FAIL
); 
 454   case IPC_DISCONNECT
: { 
 456     connection
->OnDisconnect(); 
 460     codeco
->Write8(IPC_FAIL
); 
 465 void Server_OnRequest(wxSocketServer
& server
, 
 466                       wxSocketNotify evt
, char *cdata
) 
 468   wxTCPServer 
*ipcserv 
= (wxTCPServer 
*)cdata
; 
 469   wxSocketStream 
*stream
; 
 470   wxDataInputStream 
*codeci
; 
 471   wxDataOutputStream 
*codeco
; 
 473   if (evt 
!= wxSOCKET_CONNECTION
) 
 476   /* Accept the connection, getting a new socket */ 
 477   wxSocketBase 
*sock 
= server
.Accept(); 
 479   sock
->SetNotify(wxSOCKET_INPUT_FLAG 
| wxSOCKET_LOST_FLAG
); 
 481   stream 
= new wxSocketStream(*sock
); 
 482   codeci 
= new wxDataInputStream(*stream
); 
 483   codeco 
= new wxDataOutputStream(*stream
); 
 489   msg 
= codeci
->Read8(); 
 491   if (msg 
== IPC_CONNECT
) { 
 493     topic_name 
= codeci
->ReadString(); 
 495     /* Register new socket with the notifier */ 
 496     wxTCPConnection 
*new_connection 
= 
 497          (wxTCPConnection 
*)ipcserv
->OnAcceptConnection (topic_name
); 
 498     if (new_connection
) { 
 499       if (!new_connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) { 
 500         delete new_connection
; 
 501         codeco
->Write8(IPC_FAIL
); 
 504       // Acknowledge success 
 505       codeco
->Write8(IPC_CONNECT
); 
 507       new_connection
->m_topic 
= topic_name
; 
 508       new_connection
->m_sockstrm 
= stream
; 
 509       new_connection
->m_codeci 
= codeci
; 
 510       new_connection
->m_codeco 
= codeco
; 
 511       sock
->Callback(Client_OnRequest
); 
 512       sock
->CallbackData((char *)new_connection
); 
 515       // Send failure message 
 516       codeco
->Write8(IPC_FAIL
);