Rewrote large parts of the non-DDE IPC stuff (wxTCPServer, wxTCPClient,

wxTCPConnection) to upgrade to the 'new' wxSocket code. Plenty of bugs
removed. IPC samples at samples/dde working again.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5267 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guillermo Rodriguez Garcia 2000-01-06 01:07:06 +00:00
parent e612f101d3
commit 0834112f89
2 changed files with 145 additions and 105 deletions

View File

@ -1,12 +1,14 @@
/////////////////////////////////////////////////////////////////////////////
// Name: sckipc.h
// Purpose: Interprocess communication
// Author: Julian Smart/Guilhem Lavaux (big rewrite)
// Modified by: Guilhem Lavaux 1997
// Purpose: Interprocess communication implementation (wxSocket version)
// Author: Julian Smart
// Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
// Guillermo Rodriguez (updated for wxSocket v2) Jan 2000
// Created: 1993
// RCS-ID: $Id$
// Copyright: (c) 1993 Julian Smart
// (c) 1997, 1998 Guilhem Lavaux
// Copyright: (c) Julian Smart 1993
// (c) Guilhem Lavaux 1997, 1998
// (c) 2000 Guillermo Rodriguez <guille@iies.es>
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_SCKIPC_H
@ -73,30 +75,38 @@ public:
virtual ~wxTCPConnection();
// Calls that CLIENT can make
bool Execute(const wxChar *data, int size = -1,
wxIPCFormat format = wxIPC_TEXT);
char *Request(const wxString& item, int *size = NULL,
wxIPCFormat format = wxIPC_TEXT);
bool Poke(const wxString& item, wxChar *data, int size = -1,
wxIPCFormat format = wxIPC_TEXT);
bool StartAdvise(const wxString& item);
bool StopAdvise(const wxString& item);
virtual bool Execute(const wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
virtual bool Execute(const wxString& str) { return Execute(str, -1, wxIPC_TEXT); }
virtual char *Request(const wxString& item, int *size = NULL, wxIPCFormat format = wxIPC_TEXT);
virtual bool Poke(const wxString& item, wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
virtual bool StartAdvise(const wxString& item);
virtual bool StopAdvise(const wxString& item);
// Calls that SERVER can make
bool Advise(const wxString& item, wxChar *data, int size = -1,
wxIPCFormat format = wxIPC_TEXT);
virtual bool Advise(const wxString& item, wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
// Calls that both can make
bool Disconnect();
virtual bool Disconnect(void);
// Called when we lost the peer.
bool OnDisconnect() { return TRUE; }
// Callbacks to SERVER - override at will
virtual bool OnExecute(const wxString& topic, char *data, int size, wxIPCFormat format) { return FALSE; };
virtual char *OnRequest(const wxString& topic, const wxString& item, int *size, wxIPCFormat format) { return NULL; };
virtual bool OnPoke(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) { return FALSE; };
virtual bool OnStartAdvise(const wxString& topic, const wxString& item) { return FALSE; };
virtual bool OnStopAdvise(const wxString& topic, const wxString& item) { return FALSE; };
// Callbacks to CLIENT - override at will
virtual bool OnAdvise(const wxString& topic, const wxString& item, char *data, int size, wxIPCFormat format) { return FALSE; };
// Callbacks to BOTH
// Default behaviour is to delete connection and return TRUE
virtual bool OnDisconnect(void) { delete this; return TRUE; }
// To enable the compressor
void Compress(bool on);
private:
// to prevent virtual function hiding warnings
virtual bool Execute(const wxString& str) { return(wxConnectionBase::Execute(str)); };
};
class wxTCPServer: public wxServerBase
@ -123,8 +133,8 @@ public:
virtual ~wxTCPClient();
virtual bool ValidHost(const wxString& host);
// Call this to make a connection.
// Returns NULL if cannot.
// Call this to make a connection.
// Returns NULL if cannot.
virtual wxConnectionBase *MakeConnection(const wxString& host,
const wxString& server,
const wxString& topic);

View File

@ -1,11 +1,14 @@
/////////////////////////////////////////////////////////////////////////////
// Name: sckipc.cpp
// Purpose: Interprocess communication implementation (wxSocket version)
// Author: Julian Smart, Guilhem Lavaux
// Author: Julian Smart
// Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
// Guillermo Rodriguez (updated for wxSocket v2) Jan 2000
// Created: 1993
// RCS-ID: $Id$
// Copyright: (c) Julian Smart 1993, Guilhem Lavaux 1997, 1998
// Copyright: (c) Julian Smart 1993
// (c) Guilhem Lavaux 1997, 1998
// (c) 2000 Guillermo Rodriguez <guille@iies.es>
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
@ -30,6 +33,7 @@
#include "wx/socket.h"
#include "wx/sckipc.h"
#include "wx/log.h"
#ifdef __BORLANDC__
#pragma hdrstop
@ -88,51 +92,60 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
const wxString& server_name,
const wxString& topic)
{
wxIPV4address addr;
wxSocketClient *client = new wxSocketClient();
wxSocketStream *stream = new wxSocketStream(*client);
wxDataInputStream data_is(*stream);
wxDataOutputStream data_os(*stream);
client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
wxDataInputStream *data_is = new wxDataInputStream(*stream);
wxDataOutputStream *data_os = new wxDataOutputStream(*stream);
wxIPV4address addr;
addr.Service(server_name);
addr.Hostname(host);
if (!client->Connect(addr)) {
delete client;
return NULL;
}
client->Notify(FALSE);
if (client->Connect(addr))
{
unsigned char msg;
// Send topic name, and enquire whether this has succeeded
data_os->Write8(IPC_CONNECT);
data_os->WriteString(topic);
msg = data_is->Read8();
// Send topic name, and enquire whether this has succeeded
unsigned char msg;
data_os.Write8(IPC_CONNECT);
data_os.WriteString(topic);
msg = data_is.Read8();
// OK! Confirmation.
if (msg == IPC_CONNECT) {
wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection ();
if (connection) {
if (!connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
delete connection;
return NULL;
// OK! Confirmation.
if (msg == IPC_CONNECT)
{
wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection ();
if (connection)
{
if (!connection->IsKindOf(CLASSINFO(wxTCPConnection)))
{
delete connection;
// and fall through to delete everything else
}
else
{
connection->m_topic = topic;
connection->m_sock = client;
connection->m_sockstrm = stream;
connection->m_codeci = data_is;
connection->m_codeco = data_os;
client->Callback(Client_OnRequest);
client->CallbackData((char *)connection);
client->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
client->Notify(TRUE);
return connection;
}
}
connection->m_topic = topic;
client->Callback(Client_OnRequest);
client->CallbackData((char *)connection);
client->Notify(TRUE);
return connection;
} else {
delete client;
return NULL;
}
} else {
delete client;
return NULL;
}
// something went wrong
delete data_is;
delete data_os;
delete stream;
delete client;
return NULL;
}
wxConnectionBase *wxTCPClient::OnMakeConnection()
@ -154,14 +167,15 @@ bool wxTCPServer::Create(const wxString& server_name)
wxIPV4address addr;
wxSocketServer *server;
addr.LocalHost(); // GRG
addr.Service(server_name);
// Create a socket listening on specified port
server = new wxSocketServer(addr);
server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
server->SetNotify(wxSOCKET_CONNECTION_FLAG);
server->CallbackData((char *)this);
server->SetNotify(wxSOCKET_CONNECTION_FLAG);
server->Notify(TRUE); // GRG
return TRUE;
}
@ -212,7 +226,7 @@ bool wxTCPConnection::Disconnect ()
return TRUE;
}
bool wxTCPConnection::Execute (const wxChar *data, int size, wxIPCFormat format)
bool wxTCPConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
{
if (!m_sock->IsConnected())
return FALSE;
@ -220,12 +234,12 @@ bool wxTCPConnection::Execute (const wxChar *data, int size, wxIPCFormat format)
// Prepare EXECUTE message
m_codeco->Write8(IPC_EXECUTE);
m_codeco->Write8(format);
if (size < 0)
m_codeco->WriteString(data);
else {
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
}
size = strlen(data) + 1; // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
return TRUE;
}
@ -245,7 +259,8 @@ char *wxTCPConnection::Request (const wxString& item, int *size, wxIPCFormat for
ret = m_codeci->Read8();
if (ret == IPC_FAIL)
return NULL;
else {
else
{
size_t s;
char *data = NULL;
@ -267,12 +282,12 @@ bool wxTCPConnection::Poke (const wxString& item, wxChar *data, int size, wxIPCF
m_codeco->Write8(IPC_POKE);
m_codeco->WriteString(item);
m_codeco->Write8(format);
if (size < 0)
m_codeco->WriteString(data);
else {
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
}
size = strlen(data) + 1; // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
return TRUE;
}
@ -323,12 +338,12 @@ bool wxTCPConnection::Advise (const wxString& item,
m_codeco->Write8(IPC_ADVISE);
m_codeco->WriteString(item);
m_codeco->Write8(format);
if (size < 0)
m_codeco->WriteString(data);
else {
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
}
size = strlen(data) + 1; // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
return TRUE;
}
@ -345,7 +360,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
wxString item;
// The socket handler signals us that we lost the connection: destroy all.
if (evt == wxSOCKET_LOST) {
if (evt == wxSOCKET_LOST)
{
sock.Close();
connection->OnDisconnect();
return;
@ -357,8 +373,10 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
sockstrm = connection->m_sockstrm;
msg = codeci->Read8();
switch (msg) {
case IPC_EXECUTE: {
switch (msg)
{
case IPC_EXECUTE:
{
char *data;
size_t size;
wxIPCFormat format;
@ -373,7 +391,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
delete [] data;
break;
}
case IPC_ADVISE: {
case IPC_ADVISE:
{
char *data;
size_t size;
wxIPCFormat format;
@ -389,7 +408,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
delete [] data;
break;
}
case IPC_ADVISE_START: {
case IPC_ADVISE_START:
{
item = codeci->ReadString();
bool ok = connection->OnStartAdvise (topic_name, item);
@ -400,7 +420,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
break;
}
case IPC_ADVISE_STOP: {
case IPC_ADVISE_STOP:
{
item = codeci->ReadString();
bool ok = connection->OnStopAdvise (topic_name, item);
@ -411,7 +432,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
break;
}
case IPC_POKE: {
case IPC_POKE:
{
wxIPCFormat format;
size_t size;
wxChar *data;
@ -428,7 +450,8 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
break;
}
case IPC_REQUEST: {
case IPC_REQUEST:
{
wxIPCFormat format;
item = codeci->ReadString();
@ -437,19 +460,23 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketNotify evt,
int user_size = -1;
char *user_data = connection->OnRequest (topic_name, item, &user_size, format);
if (user_data) {
if (user_data)
{
codeco->Write8(IPC_REQUEST_REPLY);
if (user_size != -1) {
codeco->Write32(user_size);
sockstrm->Write(user_data, user_size);
} else
codeco->WriteString(user_data);
} else
if (user_size == -1)
user_size = strlen(user_data) + 1; // includes final NUL
codeco->Write32(user_size);
sockstrm->Write(user_data, user_size);
}
else
codeco->Write8(IPC_FAIL);
break;
}
case IPC_DISCONNECT: {
case IPC_DISCONNECT:
{
sock.Close();
connection->OnDisconnect();
break;
@ -473,43 +500,46 @@ void Server_OnRequest(wxSocketServer& server,
/* Accept the connection, getting a new socket */
wxSocketBase *sock = server.Accept();
sock->Notify(FALSE);
sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
if (!sock->Ok())
return;
stream = new wxSocketStream(*sock);
codeci = new wxDataInputStream(*stream);
codeco = new wxDataOutputStream(*stream);
if (!sock->Ok())
return;
int msg;
msg = codeci->Read8();
if (msg == IPC_CONNECT) {
if (msg == IPC_CONNECT)
{
wxString topic_name;
topic_name = codeci->ReadString();
/* Register new socket with the notifier */
wxTCPConnection *new_connection =
(wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name);
if (new_connection) {
if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
if (new_connection)
{
if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection)))
{
delete new_connection;
codeco->Write8(IPC_FAIL);
return;
}
// Acknowledge success
codeco->Write8(IPC_CONNECT);
new_connection->m_topic = topic_name;
new_connection->m_sock = sock;
new_connection->m_sockstrm = stream;
new_connection->m_codeci = codeci;
new_connection->m_codeco = codeco;
sock->Callback(Client_OnRequest);
sock->CallbackData((char *)new_connection);
sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
sock->Notify(TRUE);
} else {
}
else
{
// Send failure message
codeco->Write8(IPC_FAIL);
}