* Added wxsocket lib and sample (I hope I don't forget some file)

* Updated some wx data and makefiles
* Updates on wxStream (reorganization)
 makefile for Windows will nearly follow
 wxSocket should work on wxGTK (I've tested it)

* IPC over Network is included


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@684 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
1998-09-06 18:28:00 +00:00
parent 560b92f577
commit f4ada56822
42 changed files with 5667 additions and 36 deletions

503
src/common/sckipc.cpp Normal file
View File

@@ -0,0 +1,503 @@
/////////////////////////////////////////////////////////////////////////////
// Name: sckipc.cpp
// Purpose: Interprocess communication implementation (wxSocket version)
// Author: Julian Smart, Guilhem Lavaux
// Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
// Created: 1993
// RCS-ID: $Id$
// Copyright: (c) Julian Smart 1993, Guilhem Lavaux 1997, 1998
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sckipc.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#ifdef WXPREC
#include <wx/wxprec.h>
#else
#include <wx/wx.h>
#endif
#include "wx/socket.h"
#include "wx/sckipc.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase)
IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase)
IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase)
#endif
// It seems to be already defined somewhere in the Xt includes.
#ifndef __XT__
// Message codes
enum {
IPC_EXECUTE = 1,
IPC_REQUEST,
IPC_POKE,
IPC_ADVISE_START,
IPC_ADVISE_REQUEST,
IPC_ADVISE,
IPC_ADVISE_STOP,
IPC_REQUEST_REPLY,
IPC_FAIL,
IPC_CONNECT,
IPC_DISCONNECT
};
#endif
void Server_OnRequest(wxSocketServer& server,
wxSocketBase::wxRequestEvent evt,
char *cdata);
void Client_OnRequest(wxSocketBase& sock,
wxSocketBase::wxRequestEvent evt,
char *cdata);
// ---------------------------------------------------------------------------
// wxTCPClient
// ---------------------------------------------------------------------------
wxTCPClient::wxTCPClient (void)
: wxClientBase()
{
}
wxTCPClient::~wxTCPClient (void)
{
}
bool wxTCPClient::ValidHost(const wxString& host)
{
wxIPV4address addr;
return addr.Hostname(host);
}
wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
const wxString& server_name,
const wxString& topic)
{
wxIPV4address addr;
wxSocketHandler *hsock = &wxSocketHandler::Master();
wxSocketClient *client = hsock->CreateClient();
wxSocketStream *stream = new wxSocketStream(*client);
wxDataStream data_s(*stream);
client->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
addr.Service(server_name);
addr.Hostname(host);
if (!client->Connect(addr)) {
delete client;
return NULL;
}
client->Notify(FALSE);
// Send topic name, and enquire whether this has succeeded
unsigned char msg;
data_s.Write8(IPC_CONNECT);
data_s.WriteString(topic);
msg = data_s.Read8();
// OK! Confirmation.
if (msg == IPC_CONNECT) {
wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection ();
if (connection) {
if (!connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
delete connection;
return NULL;
}
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;
}
return NULL;
}
wxConnectionBase *wxTCPClient::OnMakeConnection()
{
return new wxTCPConnection;
}
// ---------------------------------------------------------------------------
// wxTCPServer
// ---------------------------------------------------------------------------
wxTCPServer::wxTCPServer (void)
: wxServerBase()
{
}
bool wxTCPServer::Create(const wxString& server_name)
{
wxIPV4address addr;
wxSocketHandler *hsock = &wxSocketHandler::Master();
wxSocketServer *server;
addr.Service(server_name);
// Create a socket listening on specified port
server = hsock->CreateServer(addr);
server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
server->SetNotify(wxSocketBase::REQ_ACCEPT);
server->CallbackData((char *)this);
return TRUE;
}
wxTCPServer::~wxTCPServer (void)
{
}
wxConnectionBase *wxTCPServer::OnAcceptConnection(const wxString& topic)
{
return new wxTCPConnection();
}
// ---------------------------------------------------------------------------
// wxTCPConnection
// ---------------------------------------------------------------------------
wxTCPConnection::wxTCPConnection (void)
: wxConnectionBase(),
m_sock(NULL), m_sockstrm(NULL), m_codec(NULL)
{
}
wxTCPConnection::~wxTCPConnection (void)
{
wxDELETE(m_sock);
wxDELETE(m_codec);
wxDELETE(m_sockstrm);
}
void wxTCPConnection::Compress(bool on)
{
// Use wxLZWStream
}
// Calls that CLIENT can make.
bool wxTCPConnection::Disconnect (void)
{
// Send the the disconnect message to the peer.
m_codec->Write8(IPC_DISCONNECT);
m_sock->Close();
return TRUE;
}
bool wxTCPConnection::Execute (char *data, int size, wxDataFormat format)
{
if (!m_sock->IsConnected())
return FALSE;
// Prepare EXECUTE message
m_codec->Write8(IPC_EXECUTE);
m_codec->Write8(format);
if (size < 0)
m_codec->WriteString(data);
else {
m_codec->Write32(size);
m_codec->Write(data, size);
}
return TRUE;
}
char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat format)
{
if (!m_sock->IsConnected())
return NULL;
m_codec->Write8(IPC_REQUEST);
m_codec->WriteString(item);
m_codec->Write8(format);
// If Unpack doesn't initialize it.
int ret;
ret = m_codec->Read8();
if (ret == IPC_FAIL)
return NULL;
else {
size_t s;
char *data = NULL;
s = m_codec->Read32();
data = new char[s];
m_codec->Read(data, s);
if (size)
*size = s;
return data;
}
}
bool wxTCPConnection::Poke (const wxString& item, char *data, int size, wxDataFormat format)
{
if (!m_sock->IsConnected())
return FALSE;
m_codec->Write8(IPC_POKE);
m_codec->WriteString(item);
m_codec->Write8(format);
if (size < 0)
m_codec->WriteString(data);
else {
m_codec->Write32(size);
m_codec->Write(data, size);
}
return TRUE;
}
bool wxTCPConnection::StartAdvise (const wxString& item)
{
int ret;
if (!m_sock->IsConnected())
return FALSE;
m_codec->Write8(IPC_ADVISE_START);
m_codec->WriteString(item);
ret = m_codec->Read8();
if (ret != IPC_FAIL)
return TRUE;
else
return FALSE;
}
bool wxTCPConnection::StopAdvise (const wxString& item)
{
int msg;
if (!m_sock->IsConnected())
return FALSE;
m_codec->Write8(IPC_ADVISE_STOP);
m_codec->WriteString(item);
msg = m_codec->Read8();
if (msg != IPC_FAIL)
return TRUE;
else
return FALSE;
}
// Calls that SERVER can make
bool wxTCPConnection::Advise (const wxString& item,
char *data, int size, wxDataFormat format)
{
if (!m_sock->IsConnected())
return FALSE;
m_codec->Write8(IPC_ADVISE);
m_codec->WriteString(item);
m_codec->Write8(format);
if (size < 0)
m_codec->WriteString(data);
else {
m_codec->Write32(size);
m_codec->Write(data, size);
}
return TRUE;
}
void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
char *cdata)
{
int msg = 0;
wxTCPConnection *connection = (wxTCPConnection *)cdata;
wxDataStream *codec;
wxString topic_name = connection->m_topic;
wxString item;
// The socket handler signals us that we lost the connection: destroy all.
if (evt == wxSocketBase::EVT_LOST) {
sock.Close();
connection->OnDisconnect();
return;
}
// Receive message number.
codec = connection->m_codec;
msg = codec->Read8();
switch (msg) {
case IPC_EXECUTE: {
char *data;
size_t size;
wxDataFormat format;
format = (wxDataFormat)codec->Read8();
size = codec->Read32();
data = new char[size];
codec->Read(data, size);
connection->OnExecute (topic_name, data, size, format);
delete [] data;
break;
}
case IPC_ADVISE: {
char *data;
size_t size;
wxDataFormat format;
item = codec->ReadString();
format = (wxDataFormat)codec->Read8();
size = codec->Read32();
data = new char[size];
codec->Read(data, size);
connection->OnAdvise (topic_name, item, data, size, format);
delete [] data;
break;
}
case IPC_ADVISE_START: {
item = codec->ReadString();
bool ok = connection->OnStartAdvise (topic_name, item);
if (ok)
codec->Write8(IPC_ADVISE_START);
else
codec->Write8(IPC_FAIL);
break;
}
case IPC_ADVISE_STOP: {
item = codec->ReadString();
bool ok = connection->OnStopAdvise (topic_name, item);
if (ok)
codec->Write8(IPC_ADVISE_STOP);
else
codec->Write8(IPC_FAIL);
break;
}
case IPC_POKE: {
wxDataFormat format;
size_t size;
char *data;
item = codec->ReadString();
format = (wxDataFormat)codec->Read8();
size = codec->Read32();
data = new char[size];
codec->Read(data, size);
connection->OnPoke (topic_name, item, data, size, format);
delete [] data;
break;
}
case IPC_REQUEST: {
wxDataFormat format;
item = codec->ReadString();
format = (wxDataFormat)codec->Read8();
int user_size = -1;
char *user_data = connection->OnRequest (topic_name, item, &user_size, format);
if (user_data) {
codec->Write8(IPC_REQUEST_REPLY);
if (user_size != -1) {
codec->Write32(user_size);
codec->Write(user_data, user_size);
} else
codec->WriteString(user_data);
} else
codec->Write8(IPC_FAIL);
break;
}
case IPC_DISCONNECT: {
sock.Close();
connection->OnDisconnect();
break;
}
default:
codec->Write8(IPC_FAIL);
break;
}
}
void Server_OnRequest(wxSocketServer& server,
wxSocketBase::wxRequestEvent evt, char *cdata)
{
wxTCPServer *ipcserv = (wxTCPServer *)cdata;
wxSocketStream *stream;
wxDataStream *codec;
if (evt != wxSocketBase::EVT_ACCEPT)
return;
/* Accept the connection, getting a new socket */
wxSocketBase *sock = server.Accept();
sock->Notify(FALSE);
sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
stream = new wxSocketStream(*sock);
codec = new wxDataStream(*stream);
if (!sock->Ok())
return;
int msg;
msg = codec->Read8();
if (msg == IPC_CONNECT) {
wxString topic_name;
topic_name = codec->ReadString();
/* Register new socket with the notifier */
wxTCPConnection *new_connection =
(wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name);
if (new_connection) {
if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
delete new_connection;
codec->Write8(IPC_FAIL);
return;
}
// Acknowledge success
codec->Write8(IPC_CONNECT);
new_connection->m_topic = topic_name;
new_connection->m_sockstrm = stream;
new_connection->m_codec = codec;
sock->Callback(Client_OnRequest);
sock->CallbackData((char *)new_connection);
sock->Notify(TRUE);
} else {
// Send failure message
codec->Write8(IPC_FAIL);
}
}
}