server.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 716 行 · 第 1/2 页

CPP
716
字号
// server.cpp,v 1.6 2003/11/22 23:21:31 parsons Exp

// ============================================================================
//
// = LIBRARY
//    TAO/examples/Advanced/ch_12
//
// = FILENAME
//    server.cpp
//
// = AUTHORS
//   Source code used in TAO has been modified and adapted from the
//   code provided in the book, "Advanced CORBA Programming with C++"
//   by Michi Henning and Steve Vinoski. Copyright
//   1999. Addison-Wesley, Reading, MA.  Used with permission of
//   Addison-Wesley.
//
//   Modified for TAO by Mike Moran <mm4@cs.wustl.edu>
//
// ============================================================================

#include "server.h"
#include <algorithm>
#include "icp.h"
#include <strstream>
#include <fstream>
#include <iostream>

// The following headers are #included automatically by ACE+TAO.
// Therefore, they don't need to be included explicitly.
// #include <fstream.h>
// #include <iostream.h>

const char *Controller_oid = "Controller";

// Generic ostream inserter for exceptions. Inserts the exception
// name, if available, and the repository ID otherwise.

#if 0   // This inserter may or may not be needed for your ORB.

static ostream &
operator<< (ostream & os, const CORBA::Exception & e)
{
  CORBA::Any tmp;
  tmp <<= e;

  CORBA::TypeCode_var tc = tmp.type ();
  const char * p = tc->name ();
  if  (*p != '\0')
    os << p;
  else
    os << tc->id ();
  return os;
}

#endif

// Helper function to create object references.

static CCS::Thermometer_ptr
make_dref (PortableServer::POA_ptr poa, CCS::AssetType anum)
{
  // Convert asset number to OID.
  ostrstream ostr;
  ostr << anum << ends;
  char * anum_str = ostr.str ();
  PortableServer::ObjectId_var oid
    = PortableServer::string_to_ObjectId (anum_str);
  delete[] anum_str;

  // Look at the model via the network to determine
  // the repository ID.
  char buf[32];
  assert (ICP_get (anum, "model", buf, sizeof (buf)) == 0);
  const char * rep_id = strcmp (buf, "Sens-A-Temp") == 0
    ? "IDL:acme.com/CCS/Thermometer:1.0"
    : "IDL:acme.com/CCS/Thermostat:1.0";

  // Make a new reference.
  CORBA::Object_var obj
    = poa->create_reference_with_id (oid.in (), rep_id);
  return CCS::Thermometer::_narrow (obj.in ());
}

Controller_impl * Thermometer_impl::m_ctrl;     // static member

// Helper function to read the model string from a device.

CCS::ModelType
Thermometer_impl::
get_model ()
{
  char buf[32];
  assert (ICP_get (m_anum, "model", buf, sizeof (buf)) == 0);
  return CORBA::string_dup (buf);
}

// Helper function to read the temperature from a device.

CCS::TempType
Thermometer_impl::
get_temp ()
{
  short temp;
  assert (ICP_get (m_anum, "temperature", &temp, sizeof (temp)) == 0);
  return temp;
}

// Helper function to read the location from a device.

CCS::LocType
Thermometer_impl::
get_loc ()
{
  char buf[32];
  assert (ICP_get (m_anum, "location", buf, sizeof (buf)) == 0);
  return CORBA::string_dup (buf);
}

// Helper function to set the location of a device.

void
Thermometer_impl::
set_loc (const char * loc)
{
  assert (ICP_set (m_anum, "location", loc) == 0);
}

// Constructor.

Thermometer_impl::
Thermometer_impl (CCS::AssetType anum) : m_anum (anum)
{
  m_ctrl->add_impl (anum, this);   // Add self to controller's set
}

// Destructor.

Thermometer_impl::
~Thermometer_impl ()
{
  if  (m_ctrl->exists (m_anum))
    m_ctrl->add_impl (m_anum, 0);    // Clear servant pointer
}

// IDL model attribute.

CCS::ModelType
Thermometer_impl::
model () throw (CORBA::SystemException)
{
  return get_model ();
}

// IDL asset_num attribute.

CCS::AssetType
Thermometer_impl::
asset_num () throw (CORBA::SystemException)
{
  return m_anum;
}

// IDL temperature attribute.

CCS::TempType
Thermometer_impl::
temperature () throw (CORBA::SystemException)
{
  return get_temp ();
}

// IDL location attribute accessor.

CCS::LocType
Thermometer_impl::
location () throw (CORBA::SystemException)
{
  return get_loc ();
}

// IDL remove operation.

void
Thermometer_impl::
remove () throw (CORBA::SystemException)
{
  m_ctrl->remove_impl (m_anum);
  assert (ICP_offline (m_anum) == 0);
  // delete this;
}

// IDL location attribute modifier.

void
Thermometer_impl::
location (const char *loc) throw (CORBA::SystemException)
{
  set_loc (loc);
}

//----------------------------------------------------------------

// Helper function to get a thermostat's nominal temperature.

CCS::TempType
Thermostat_impl::
get_nominal_temp ()
{
  short temp;
  assert (ICP_get (m_anum, "nominal_temp", &temp, sizeof (temp)) == 0);
  return temp;
}

// Helper function to set a thermostat's nominal temperature.

CCS::TempType
Thermostat_impl::
set_nominal_temp (CCS::TempType new_temp)
throw (CCS::Thermostat::BadTemp)
{
  short old_temp;

  // We need to return the previous nominal temperature,
  // so we first read the current nominal temperature before
  // changing it.
  assert (ICP_get (m_anum, "nominal_temp", &old_temp, sizeof (old_temp)) == 0);

  // Now set the nominal temperature to the new value.
  if  (ICP_set (m_anum, "nominal_temp", &new_temp) != 0)
    {
      // If ICP_set () failed, read this thermostat's minimum and
      // maximum so we can initialize the BadTemp exception.
      CCS::Thermostat::BtData btd;
      ICP_get (m_anum, "MIN_TEMP",
               &btd.min_permitted, sizeof (btd.min_permitted));
      ICP_get (m_anum, "MAX_TEMP",
               &btd.max_permitted, sizeof (btd.max_permitted));
      btd.requested = new_temp;
      btd.error_msg = CORBA::string_dup (new_temp > btd.max_permitted ? "Too hot" : "Too cold");
      throw CCS::Thermostat::BadTemp (btd);
    }
  return old_temp;
}

// Constructor.

Thermostat_impl::
Thermostat_impl (CCS::AssetType anum) : Thermometer_impl (anum)
{
  // Intentionally empty.
}

// Destructor.

Thermostat_impl::
~Thermostat_impl ()
{
  // Intentionally empty.
}

// IDL get_nominal operation.

CCS::TempType
Thermostat_impl::
get_nominal () throw (CORBA::SystemException)
{
  return get_nominal_temp ();
}

// IDL set_nominal operation.

CCS::TempType
Thermostat_impl::
set_nominal (CCS::TempType new_temp)
throw (CORBA::SystemException, CCS::Thermostat::BadTemp)
{
  return set_nominal_temp (new_temp);
}

// Helper function to add an entry to the asset map.

void
Controller_impl::
add_impl (CCS::AssetType anum, Thermometer_impl * tip)
{
  m_assets[anum] = tip;
}

// Helper function to remove an entry from the asset map.

void
Controller_impl::
remove_impl (CCS::AssetType anum)
{
  m_assets.erase (anum);
}

// Helper function to locate a servant in the asset map.

bool
Controller_impl::
exists (CCS::AssetType anum)
{
  return m_assets.find (anum) != m_assets.end ();
}

// Constructor

Controller_impl::
Controller_impl (PortableServer::POA_ptr poa,
                 const char *asset_file)
  throw (int)
    : m_poa (PortableServer::POA::_duplicate (poa)),
      m_asset_file (asset_file)
{
  fstream afile (m_asset_file.in (), ios::in|ios::out, 0666);
  if  (!afile)
    {
      cerr << "Cannot open " << m_asset_file.in () << endl;
      throw 0;
    }
  CCS::AssetType anum;

  while  (afile >> anum)
    m_assets[anum] = 0;

  //afile.close ();
  //if  (!afile) {
  //    cerr << "Cannot close " << m_asset_file << endl;
  //    throw 0;
  //}
}

// Destructor

Controller_impl::
~Controller_impl ()
{
  // Write out the current set of asset numbers
  // and clean up all servant instances.
  ofstream afile (m_asset_file.in ());
  if  (!afile)
    {
      cerr << "Cannot open " << m_asset_file.in () << endl;
      assert (0);
    }
  AssetMap::iterator i;

  for  (i = m_assets.begin (); i != m_assets.end (); i++)
    {
      afile << i->first << endl;
      if  (!afile)
        {
          cerr << "Cannot update " << m_asset_file.in () << endl;
          assert (0);
        }
      delete i->second;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?