]>
git.saurik.com Git - wxWidgets.git/blob - src/common/sckipc.cpp
694b94d33697ff4b96590722afcfc3c9716dc3d4
   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
, 
  63                       wxSocketBase::wxRequestEvent evt
, 
  65 void Client_OnRequest(wxSocketBase
& sock
, 
  66                       wxSocketBase::wxRequestEvent evt
, 
  69 // --------------------------------------------------------------------------- 
  71 // --------------------------------------------------------------------------- 
  73 wxTCPClient::wxTCPClient (void) 
  78 wxTCPClient::~wxTCPClient (void) 
  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   wxSocketHandler 
*hsock 
= &wxSocketHandler::Master(); 
  95   wxSocketClient 
*client 
= hsock
->CreateClient(); 
  96   wxSocketStream 
*stream 
= new wxSocketStream(*client
); 
  97   wxDataInputStream 
data_is(*stream
); 
  98   wxDataOutputStream 
data_os(*stream
); 
 100   client
->SetNotify(wxSocketBase::REQ_READ 
| wxSocketBase::REQ_LOST
); 
 101   addr
.Service(server_name
); 
 104   if (!client
->Connect(addr
)) { 
 108   client
->Notify(FALSE
); 
 110   // Send topic name, and enquire whether this has succeeded 
 113   data_os
.Write8(IPC_CONNECT
); 
 114   data_os
.WriteString(topic
); 
 116   msg 
= data_is
.Read8(); 
 119   if (msg 
== IPC_CONNECT
) { 
 120     wxTCPConnection 
*connection 
= (wxTCPConnection 
*)OnMakeConnection (); 
 122       if (!connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) { 
 126       connection
->m_topic 
= topic
; 
 127       client
->Callback(Client_OnRequest
); 
 128       client
->CallbackData((char *)connection
); 
 129       client
->Notify(TRUE
); 
 142 wxConnectionBase 
*wxTCPClient::OnMakeConnection() 
 144   return new wxTCPConnection
; 
 147 // --------------------------------------------------------------------------- 
 149 // --------------------------------------------------------------------------- 
 151 wxTCPServer::wxTCPServer (void) 
 156 bool wxTCPServer::Create(const wxString
& server_name
) 
 159   wxSocketHandler 
*hsock 
= &wxSocketHandler::Master(); 
 160   wxSocketServer 
*server
; 
 162   addr
.Service(server_name
); 
 164   // Create a socket listening on specified port 
 165   server 
= hsock
->CreateServer(addr
); 
 166   server
->Callback((wxSocketBase::wxSockCbk
)Server_OnRequest
); 
 167   server
->SetNotify(wxSocketBase::REQ_ACCEPT
); 
 169   server
->CallbackData((char *)this); 
 174 wxTCPServer::~wxTCPServer(void) 
 178 wxConnectionBase 
*wxTCPServer::OnAcceptConnection( const wxString
& WXUNUSED(topic
) ) 
 180   return new wxTCPConnection(); 
 183 // --------------------------------------------------------------------------- 
 185 // --------------------------------------------------------------------------- 
 187 wxTCPConnection::wxTCPConnection (void) 
 188   : wxConnectionBase(), 
 189     m_sock(NULL
), m_sockstrm(NULL
), m_codeci(NULL
), m_codeco(NULL
) 
 193 wxTCPConnection::wxTCPConnection(char *buffer
, int size
) 
 197 wxTCPConnection::~wxTCPConnection (void) 
 202   wxDELETE(m_sockstrm
); 
 205 void wxTCPConnection::Compress(bool WXUNUSED(on
)) 
 210 // Calls that CLIENT can make. 
 211 bool wxTCPConnection::Disconnect (void) 
 213   // Send the the disconnect message to the peer. 
 214   m_codeco
->Write8(IPC_DISCONNECT
); 
 220 bool wxTCPConnection::Execute (wxChar 
*data
, int size
, wxIPCFormat format
) 
 222   if (!m_sock
->IsConnected()) 
 225   // Prepare EXECUTE message 
 226   m_codeco
->Write8(IPC_EXECUTE
); 
 227   m_codeco
->Write8(format
); 
 229     m_codeco
->WriteString(data
); 
 231     m_codeco
->Write32(size
); 
 232     m_sockstrm
->Write(data
, size
); 
 238 char *wxTCPConnection::Request (const wxString
& item
, int *size
, wxIPCFormat format
) 
 240   if (!m_sock
->IsConnected()) 
 243   m_codeco
->Write8(IPC_REQUEST
); 
 244   m_codeco
->WriteString(item
); 
 245   m_codeco
->Write8(format
); 
 247   // If Unpack doesn't initialize it. 
 250   ret 
= m_codeci
->Read8(); 
 257     s 
= m_codeci
->Read32(); 
 259     m_sockstrm
->Read(data
, s
); 
 267 bool wxTCPConnection::Poke (const wxString
& item
, wxChar 
*data
, int size
, wxIPCFormat format
) 
 269   if (!m_sock
->IsConnected()) 
 272   m_codeco
->Write8(IPC_POKE
); 
 273   m_codeco
->WriteString(item
); 
 274   m_codeco
->Write8(format
); 
 276     m_codeco
->WriteString(data
); 
 278     m_codeco
->Write32(size
); 
 279     m_sockstrm
->Write(data
, size
); 
 285 bool wxTCPConnection::StartAdvise (const wxString
& item
) 
 289   if (!m_sock
->IsConnected()) 
 292   m_codeco
->Write8(IPC_ADVISE_START
); 
 293   m_codeco
->WriteString(item
); 
 295   ret 
= m_codeci
->Read8(); 
 303 bool wxTCPConnection::StopAdvise (const wxString
& item
) 
 307   if (!m_sock
->IsConnected()) 
 310   m_codeco
->Write8(IPC_ADVISE_STOP
); 
 311   m_codeco
->WriteString(item
); 
 313   msg 
= m_codeci
->Read8(); 
 321 // Calls that SERVER can make 
 322 bool wxTCPConnection::Advise (const wxString
& item
, 
 323                               wxChar 
*data
, int size
, wxIPCFormat format
) 
 325   if (!m_sock
->IsConnected()) 
 328   m_codeco
->Write8(IPC_ADVISE
); 
 329   m_codeco
->WriteString(item
); 
 330   m_codeco
->Write8(format
); 
 332     m_codeco
->WriteString(data
); 
 334     m_codeco
->Write32(size
); 
 335     m_sockstrm
->Write(data
, size
); 
 341 void Client_OnRequest(wxSocketBase
& sock
, wxSocketBase::wxRequestEvent evt
, 
 345   wxTCPConnection 
*connection 
= (wxTCPConnection 
*)cdata
; 
 346   wxDataInputStream 
*codeci
; 
 347   wxDataOutputStream 
*codeco
;  
 348   wxSocketStream 
*sockstrm
; 
 349   wxString topic_name 
= connection
->m_topic
; 
 352   // The socket handler signals us that we lost the connection: destroy all. 
 353   if (evt 
== wxSocketBase::EVT_LOST
) { 
 355     connection
->OnDisconnect(); 
 359   // Receive message number. 
 360   codeci 
= connection
->m_codeci
; 
 361   codeco 
= connection
->m_codeco
; 
 362   sockstrm 
= connection
->m_sockstrm
; 
 363   msg 
= codeci
->Read8(); 
 371     format 
= (wxIPCFormat
)codeci
->Read8(); 
 372     size 
= codeci
->Read32(); 
 373     data 
= new char[size
]; 
 374     sockstrm
->Read(data
, size
); 
 376     connection
->OnExecute (topic_name
, data
, size
, format
); 
 386     item 
= codeci
->ReadString(); 
 387     format 
= (wxIPCFormat
)codeci
->Read8(); 
 388     size 
= codeci
->Read32(); 
 389     data 
= new char[size
]; 
 390     sockstrm
->Read(data
, size
); 
 392     connection
->OnAdvise (topic_name
, item
, data
, size
, format
); 
 397   case IPC_ADVISE_START
: { 
 398     item 
= codeci
->ReadString(); 
 400     bool ok 
= connection
->OnStartAdvise (topic_name
, item
); 
 402       codeco
->Write8(IPC_ADVISE_START
); 
 404       codeco
->Write8(IPC_FAIL
); 
 408   case IPC_ADVISE_STOP
: { 
 409     item 
= codeci
->ReadString(); 
 411     bool ok 
= connection
->OnStopAdvise (topic_name
, item
); 
 413       codeco
->Write8(IPC_ADVISE_STOP
); 
 415       codeco
->Write8(IPC_FAIL
); 
 424     item 
= codeci
->ReadString(); 
 425     format 
= (wxIPCFormat
)codeci
->Read8(); 
 426     size 
= codeci
->Read32(); 
 427     data 
= new wxChar
[size
]; 
 428     sockstrm
->Read(data
, size
); 
 430     connection
->OnPoke (topic_name
, item
, data
, size
, format
); 
 439     item 
= codeci
->ReadString(); 
 440     format 
= (wxIPCFormat
)codeci
->Read8(); 
 443     char *user_data 
= connection
->OnRequest (topic_name
, item
, &user_size
, format
); 
 446       codeco
->Write8(IPC_REQUEST_REPLY
); 
 447       if (user_size 
!= -1) { 
 448         codeco
->Write32(user_size
); 
 449         sockstrm
->Write(user_data
, user_size
); 
 451         codeco
->WriteString(user_data
); 
 453       codeco
->Write8(IPC_FAIL
); 
 457   case IPC_DISCONNECT
: { 
 459     connection
->OnDisconnect(); 
 463     codeco
->Write8(IPC_FAIL
); 
 468 void Server_OnRequest(wxSocketServer
& server
, 
 469                       wxSocketBase::wxRequestEvent evt
, char *cdata
) 
 471   wxTCPServer 
*ipcserv 
= (wxTCPServer 
*)cdata
; 
 472   wxSocketStream 
*stream
; 
 473   wxDataInputStream 
*codeci
; 
 474   wxDataOutputStream 
*codeco
; 
 476   if (evt 
!= wxSocketBase::EVT_ACCEPT
) 
 479   /* Accept the connection, getting a new socket */ 
 480   wxSocketBase 
*sock 
= server
.Accept(); 
 482   sock
->SetNotify(wxSocketBase::REQ_READ 
| wxSocketBase::REQ_LOST
); 
 484   stream 
= new wxSocketStream(*sock
); 
 485   codeci 
= new wxDataInputStream(*stream
); 
 486   codeco 
= new wxDataOutputStream(*stream
); 
 492   msg 
= codeci
->Read8(); 
 494   if (msg 
== IPC_CONNECT
) { 
 496     topic_name 
= codeci
->ReadString(); 
 498     /* Register new socket with the notifier */ 
 499     wxTCPConnection 
*new_connection 
= 
 500          (wxTCPConnection 
*)ipcserv
->OnAcceptConnection (topic_name
); 
 501     if (new_connection
) { 
 502       if (!new_connection
->IsKindOf(CLASSINFO(wxTCPConnection
))) { 
 503         delete new_connection
; 
 504         codeco
->Write8(IPC_FAIL
); 
 507       // Acknowledge success 
 508       codeco
->Write8(IPC_CONNECT
); 
 510       new_connection
->m_topic 
= topic_name
; 
 511       new_connection
->m_sockstrm 
= stream
; 
 512       new_connection
->m_codeci 
= codeci
; 
 513       new_connection
->m_codeco 
= codeco
; 
 514       sock
->Callback(Client_OnRequest
); 
 515       sock
->CallbackData((char *)new_connection
); 
 518       // Send failure message 
 519       codeco
->Write8(IPC_FAIL
);