Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> удаленный вызов. детали, реализация, архитектура, у темы новое название! 
:(
    Опции темы
boostcoder
Дата 27.10.2010, 02:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



вот.
даже работает smile 
честно признаюсь, я догадывался что оно должно работать именно так, потому и создал на днях эту тему. но что-то меня отвлекло..

сервер:
Код

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>

const int bufsize = 1024;
typedef boost::array<char, bufsize> buffer;

/***************************************************************************/

struct server {
   server(boost::asio::io_service& ios, boost::uint16_t port)
      :_acceptor(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
      _socket(ios),
      _idx(0)
   {
      _acceptor.async_accept(_socket,
         boost::bind(&server::handle_accept, this, boost::asio::placeholders::error)
      );
   }

   ~server() {
      std::cout << "destructing server" << std::endl;
   }

   void handle_accept(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << "server: incoming connection from: " << _socket.remote_endpoint().address().to_string() << std::endl;
         start_read();
         start_write();
      } else {
         std::cout << "server: error on server accept" << std::endl;
      }
   }

   void start_read() {
      boost::asio::async_read(_socket,
         boost::asio::buffer(_inbuffer, _inbuffer.size()),
         boost::bind(&server::read_handler, this, boost::asio::placeholders::error)
      );
   }

   void start_write() {
      sprintf(_outbuffer.begin(), "%d", _idx++);
      boost::asio::async_write(_socket,
         boost::asio::buffer(_outbuffer, _outbuffer.size()),
         boost::bind(&server::write_handler, this, boost::asio::placeholders::error)
      );
   }

   void read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << "server: read message form client \"" << _inbuffer.begin() << "\"" << std::endl;
      } else {
         std::cout << "server: read from client error" << std::endl;
      }
      start_read();
   }

   void write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << "server: message writen to client \"" << _outbuffer.begin() << "\"" << std::endl;
      } else {
         std::cout << "server: error on writing to client" << std::endl;
      }
      start_write();
   }

private:
   boost::asio::ip::tcp::acceptor _acceptor;
   boost::asio::ip::tcp::socket _socket;
   int _idx;
   buffer _inbuffer;
   buffer _outbuffer;
};

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      server server(ios, 44550);
      ios.run();
   } catch (const std::exception& e) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
}

/***************************************************************************/


собирать так:
Цитата

g++ -oserver server.cpp -lboost_system


клиент:
Код

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>

const int bufsize = 1024;
typedef boost::array<char, bufsize> buffer;

/***************************************************************************/
struct client {
   client(boost::asio::io_service& ios, const char* ip, boost::uint16_t port)
      :_socket(ios),
      _idx(0)
   {
      boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(ip), port);
      _socket.connect(endpoint);
      std::cout << "client: connected to server" << std::endl;
      /**  */
      start_write();
      start_read();
   }

   ~client() {
      _socket.close();
      std::cout << "destructing client" << std::endl;
   }

   void start_write() {
      sprintf(_outbuffer.begin(), "%d", _idx++);
      boost::asio::async_write(_socket,
         boost::asio::buffer(_outbuffer, _outbuffer.size()),
         boost::bind(&client::write_handler, this, boost::asio::placeholders::error)
      );
   }

   void start_read() {
      boost::asio::async_read(_socket,
         boost::asio::buffer(_inbuffer, _inbuffer.size()),
         boost::bind(&client::read_handler, this, boost::asio::placeholders::error)
      );
   }

   void write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << "client: message writen to server \"" << _outbuffer.begin() << "\"" << std::endl;
      } else {
         std::cout << "client: error on writing to server" << std::endl;
      }
      start_write();
   }

   void read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << "client: message read from server \"" << _inbuffer.begin() << "\""<< std::endl;
      } else {
         std::cout << "client: error read from server" << std::endl;
      }
      start_read();
   }

private:
   boost::asio::ip::tcp::socket _socket;
   int _idx;
   buffer _inbuffer;
   buffer _outbuffer;
};

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      client client(ios, "127.0.0.1", 44550);
      ios.run();
   } catch (const std::exception& e) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
}

/***************************************************************************/


собирать так:
Цитата

g++ -oclient client.cpp -lboost_system

PM WWW   Вверх
mes
Дата 27.10.2010, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.10.2010,  01:33 Найти цитируемый пост)
вот.
даже работает  

 smile 

итак старт положен..  "сырые" данные можете отправлять.. чтоб не путаться назовем объекты этого уровня net_client и net_server..

теперь создаем еще одного clienta, который будет посредством net_client`a отправлять уже типизированные сообщения.. 
и еще один сервер, который на основе net_servera будет по id в карте вызывать нужный диспетчер
для начала диспетчер такого вида :
Код

  struct dispatcher { void dispatch () { std::cout <<"dispatched"; } };



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.10.2010, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



в следующем варианте, и клиент и сервер, изначально должны находится в режиме чтения. так?

зы
вот теперь я точно понял идею )

PM WWW   Вверх
mes
Дата 27.10.2010, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.10.2010,  14:59 Найти цитируемый пост)
в следующем варианте, и клиент и сервер, изначально должны находится в режиме чтения. так?

речь идет о сокетах ? вообще то должны быть в режиме ожидания, готовые к двусторонней передаче.. т.е как для записи, так и для чтения.. 
( я говорю с точки зрения пользователя сокета.. как там внутри я не  знаю )



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.10.2010, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



т.е. после подключения, клиент и сервер становятся в операцию асинхронного чтения на сокете? полагаю, так логичнее. т.к. изначально мы не зависим от того, кто ведущий а кто ведомый. и любой из них может первым послать пакет.
PM WWW   Вверх
mes
Дата 27.10.2010, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(mes @  27.10.2010,  07:51 Найти цитируемый пост)
и еще один сервер, который на основе net_servera будет по id в карте вызывать нужный диспетчер

вобще-то это уже будет не сервер..а сессия (или удаленный client.. ) но так как у нас (насколько я понял) сервер на одного клиента, то пока пойдет, потом будет виднее где подправить smile

Добавлено @ 16:31
Цитата(boostcoder @  27.10.2010,  15:29 Найти цитируемый пост)
и любой из них может первым послать пакет. 

 smile 

я был против выражения "установлен на чтение", так как тогда логически  не возможна запись.. но если не воспринимать буквально, то все верно 
smile

Добавлено через 3 минуты и 9 секунд
Цитата(boostcoder @  27.10.2010,  15:29 Найти цитируемый пост)
 т.к. изначально мы не зависим от того, кто ведущий а кто ведомый

значит все таки столько страниц темы были не напрасны  smile 

Это сообщение отредактировал(а) mes - 27.10.2010, 16:32


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.10.2010, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



к примеру: клиент подключился к серверу. оба читают из сокета.
сервер производит запись. но т.к. клиент ожидает записи в сокет, он читает пакет, снова становится в режим чтения, что-то выполняет с прочитанным пакетом.
так?

еще любопытно, каким образом можно реализовать пакеты двух типов? т.е. пакеты на которые нужно посылать ответ, и пакеты без ответов?

Добавлено через 7 минут и 38 секунд
Цитата(mes @  27.10.2010,  16:30 Найти цитируемый пост)
значит все таки столько страниц темы были не напрасны

 smile 
PM WWW   Вверх
mes
Дата 27.10.2010, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.10.2010,  15:34 Найти цитируемый пост)
к примеру: клиент подключился к серверу. оба читают из сокета.
сервер производит запись. но т.к. клиент ожидает записи в сокет, он читает пакет, снова становится в режим чтения, что-то выполняет с прочитанным пакетом.
так?

висят себе два сокета никого не трогют, в один написали, друг подал сигнал, и его прочитали.. 
smile

Добавлено через 30 секунд
Цитата(boostcoder @  27.10.2010,  15:34 Найти цитируемый пост)
еще любопытно, каким образом можно реализовать пакеты двух типов? т.е. пакеты на которые нужно посылать ответ, и пакеты без ответов?

никаким образом этого не нужно ( и не придется) делать smile



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 27.10.2010, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  27.10.2010,  16:50 Найти цитируемый пост)
висят себе два сокета никого не трогют, в один написали, друг подал сигнал, и его прочитали.. 

ну да.

Цитата(mes @  27.10.2010,  16:50 Найти цитируемый пост)
никаким образом этого не нужно ( и не придется) делать

ок.

сейчас код выдам.

PM WWW   Вверх
boostcoder
Дата 28.10.2010, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



если я все правильно понял, то вот.
код компилиться, но не завершен, т.к. некоторые моменты не ясны.
а именно:
1. клиент, при посылке команды, каким образом будет знать, на какую команду ждать ответа, а на какую нет?
2. серверу, чтоб послать ответ на какую-то команду, так же как и клиенту нужно знать, на какую команду отвечать, а на какую нет.

хидер:
Код


#include <iostream>
#include <memory>
#include <functional>

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <boost/lexical_cast.hpp>

/***************************************************************************/

static const boost::uint16_t  port = 44550;
static const char*            host = "127.0.0.1";

/***************************************************************************/

struct constants {
   enum { header_length = 12 };
   enum { body_length = 1024*32 };
   enum { client_server, server_client };
   typedef boost::array<char, header_length> header_buffer;
   typedef boost::array<char, body_length> body_buffer;
};

/***************************************************************************/

struct header_coders {
   struct header {
      boost::int32_t    id;
      boost::uint32_t   direction;
      boost::uint32_t   body_length;
   };

   template<typename T>
   static constants::header_buffer encode_header(const std::string& b) {
      constants::header_buffer header;
      sprintf(header.data(), "%04d%02d%06d", T::meta_id, T::meta_dir, b.length());
      return header;
   }

   static header decode_header(const constants::header_buffer& data) {
      header hdr;
      sscanf(data.data(), "%04d%02d%06d", &hdr.id, &hdr.direction, &hdr.body_length);
      return hdr;
   }
};

/***************************************************************************/

inline std::ostream& operator<< (std::ostream& os, const header_coders::header& hdr) {
   os << "id:" << hdr.id << ", dir:" << hdr.direction << ", len:" << hdr.body_length << std::endl;
   return os;
}

/***************************************************************************/

struct notice { enum { id = 0 }; };
struct login  { enum { id = 1 }; };
struct quit   { enum { id = 2 }; };
struct ping   { enum { id = 3 }; };
struct pong   { enum { id = 4 }; };

/***************************************************************************/

struct i_invoker {
   virtual void dispatch(constants::header_buffer&, constants::body_buffer&) = 0;
};
typedef std::shared_ptr<i_invoker> i_invoker_ptr;

template<typename T, typename C>
struct invoker: i_invoker {
   typedef void(C::*handler_t)(T&);

   invoker(C* p, handler_t h):_this(p),_handler(h) {}

   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      T data;
      deserializer(data, h, b);
      (*_this.*_handler)(data);
      serializer(h, b, data);
   }

private:
   void deserializer(T& t, const constants::header_buffer&, const constants::body_buffer&) {
      t = T();
   }

   void serializer(constants::header_buffer&, constants::body_buffer&, const T&) {
   }

private:
   C* _this;
   handler_t _handler;
};

/***************************************************************************/

struct i_implementation {
   virtual void notice_handler(notice&) = 0;
   virtual void login_handler(login&) = 0;
   virtual void quit_handler(quit&) = 0;
   virtual void ping_handler(ping&) = 0;
   virtual void pong_handler(pong&) = 0;

   i_implementation() {
      _map[0] = i_invoker_ptr(new invoker<notice, i_implementation>(this, &i_implementation::notice_handler));
      _map[1] = i_invoker_ptr(new invoker<login, i_implementation>(this, &i_implementation::login_handler));
      _map[2] = i_invoker_ptr(new invoker<quit, i_implementation>(this, &i_implementation::quit_handler));
      _map[3] = i_invoker_ptr(new invoker<ping, i_implementation>(this, &i_implementation::ping_handler));
      _map[4] = i_invoker_ptr(new invoker<pong, i_implementation>(this, &i_implementation::pong_handler));
   }
   
   virtual void dispatch(constants::header_buffer& h, constants::body_buffer& b) {
      int id = header_coders::decode_header(h).id;
      if ( _map.find(id) == _map.end() ) {
         throw std::runtime_error("for type::id(" + boost::lexical_cast<std::string>(id) + ") handler not registered!");
      }
      _map[id]->dispatch(h, b);
   }

private:
   std::map<int, i_invoker_ptr> _map;
};

/***************************************************************************/


реализация:
Код


#include "header.hpp"

/***************************************************************************/

struct implementation: i_implementation {
   void notice_handler(notice&) {
      std::cout << "called: " << __PRETTY_FUNCTION__ << std::endl;
   }
   
   void login_handler(login&) {
      std::cout << "called: " << __PRETTY_FUNCTION__ << std::endl;
   }
   
   void quit_handler(quit&) {
      std::cout << "called: " << __PRETTY_FUNCTION__ << std::endl;
   }
   
   void ping_handler(ping&) {
      std::cout << "called: " << __PRETTY_FUNCTION__ << std::endl;
   }
   
   void pong_handler(pong&) {
      std::cout << "called: " << __PRETTY_FUNCTION__ << std::endl;
   }
};

/***************************************************************************/

struct server {
   server(boost::asio::io_service& ios, boost::uint16_t port)
      :_acceptor(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
      _socket(ios),
      _idx(0),
      _impl(new implementation())
   {
      _acceptor.async_accept(_socket,
         boost::bind(&server::handle_accept, this, boost::asio::placeholders::error)
      );
   }

   ~server() {
      std::cout << "destructing server" << std::endl;
   }

   void handle_accept(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout
            << "server: incoming connection from: "
            << _socket.remote_endpoint().address().to_string() << std::endl;
         start_read();
      } else {
         std::cout << "server: error on server accept" << std::endl;
      }
   }

   void start_read() {
      boost::asio::async_read(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&server::header_read_handler, this, boost::asio::placeholders::error)
      );
   }

   void header_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         std::cout << header_coders::decode_header(_header) << std::endl;
         boost::asio::async_read(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&server::body_read_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "server: header read error" << std::endl;
      } 
   }

   void body_read_handler(const boost::system::error_code& e) {
      if ( !e ) {
         _impl->dispatch(_header, _body);
      } else {
      }
      start_read();
   }

   void start_write() {
      boost::asio::async_write(_socket,
         boost::asio::buffer(_header, _header.size()),
         boost::bind(&server::header_write_handler, this, boost::asio::placeholders::error)
      );
   }

   void header_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
         boost::asio::async_read(_socket,
            boost::asio::buffer(_body, header_coders::decode_header(_header).body_length),
            boost::bind(&server::body_write_handler, this, boost::asio::placeholders::error)
         );
      } else {
         std::cout << "server: header write error" << std::endl;
      }
      start_write();
   }

   void body_write_handler(const boost::system::error_code& e) {
      if ( !e ) {
      } else {
      }
   }
   
   constants::header_buffer _header;
   constants::body_buffer _body;

private:
   boost::asio::ip::tcp::acceptor _acceptor;
   boost::asio::ip::tcp::socket _socket;
   int _idx;
   std::shared_ptr<implementation> _impl;
};

/***************************************************************************/

int main() {
   try {
      boost::asio::io_service ios;
      server server(ios, port);
      ios.run();
   } catch (const std::exception& e) {
      std::cout << "(exception): " << e.what() << std::endl;
   }
}

/***************************************************************************/


PM WWW   Вверх
mes
Дата 28.10.2010, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.10.2010,  23:21 Найти цитируемый пост)
1. клиент, при посылке команды, каким образом будет знать, на какую команду ждать ответа, а на какую нет?
2. серверу, чтоб послать ответ на какую-то команду, так же как и клиенту нужно знать, на какую команду отвечать, а на какую нет.

опять )) ничего лишнего ! ) только то что было в задании )
ну ладно .. 
сервер не посылает ответ, как таковой, он просто принимает команды и работает и побрабатывает их..
если ему когда нибудь (в зависмости от логики обработки, и независимо от приема команды клиента) захочеться послать клиенту команду, он просто ее посылает.. 
smile

сейчас код гляну

Добавлено через 14 минут и 47 секунд
посмотрел.. как и предполагалось по вступительным вопросам к коду.. опять вставили свою лепту.. smile
ну в принципе ничего так, только надо  вытащить нужное, и избавиться от лишнего.. 



--------------------
PM MAIL WWW   Вверх
mes
Дата 28.10.2010, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  27.10.2010,  23:21 Найти цитируемый пост)
struct i_implementation {

по коду я понял, что у вас предполагается одинаковая база как для сервера, так и для клиента?
это жесткая привязка, которая может заставить пользователя писать костыль.. 

Цитата(boostcoder @  27.10.2010,  23:21 Найти цитируемый пост)
struct server {

Цитата(boostcoder @  27.10.2010,  23:21 Найти цитируемый пост)
  std::shared_ptr<implementation> _impl;

это у Вас моноблок получается.. нехорошо.. 

Цитата(boostcoder @  27.10.2010,  23:21 Найти цитируемый пост)
struct i_invoker {

к инвокерам претензий в принципе нет



--------------------
PM MAIL WWW   Вверх
mes
Дата 28.10.2010, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



пока оставим сервер в покое.. принимает - молодец, с него пока хватит.. 
(только к клиенту этот подход не применять, и не отходить от нашего нижепредложенного плана )
рассмотрим net_client... 
нам важны сейчас две его функции , отправки и приема сырых данных.. 
сырые данные (исходя из кода) у нас выражены как (header&, body&)
на клиентена надо добавить два объекта.. rpc_sender и rpc_receiver
выглядят так
Код

struct rpc_sender {
  
   template<typename T>
   void send (const T&) {  ... raw_send (.. , ..);  }
   std::function<void(header&, body&)> raw_send;
};

Код

struct rpc_receiver {
  
   void dispatch (header&, body&) {
         std::cout << ..
   }
};

привязка к net_clientу посредством bind. 
для проверки можно связать сендер и ресивер непосредственно .. 

и еще раз ничего лишнего ! smile
фактически только реализовать сендер и привязку.. 

Это сообщение отредактировал(а) mes - 28.10.2010, 09:17


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 28.10.2010, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  28.10.2010,  08:36 Найти цитируемый пост)
опять )) ничего лишнего ! ) только то что было в задании )

это правда. я забежал вперед. просто в момент написания, мне казалось что идею я понял целиком..но когда дошло дело до отправки ответа, я понял, что ничего не понял..

Цитата(mes @  28.10.2010,  08:36 Найти цитируемый пост)
сервер не посылает ответ, как таковой, он просто принимает команды и работает и побрабатывает их..
если ему когда нибудь (в зависмости от логики обработки, и независимо от приема команды клиента) захочеться послать клиенту команду, он просто ее посылает.. 

т.е. команды для клиента и сервера разные? не связанные между собой?

Цитата(mes @  28.10.2010,  08:36 Найти цитируемый пост)
надо  вытащить нужное, и избавиться от лишнего.. 

от чего именно избавится?

Цитата(mes @  28.10.2010,  08:59 Найти цитируемый пост)
по коду я понял, что у вас предполагается одинаковая база как для сервера, так и для клиента?
это жесткая привязка, которая может заставить пользователя писать костыль.. 

это именно тот момент, из-за которого я недописал реализацию.

Цитата(mes @  28.10.2010,  08:59 Найти цитируемый пост)
это у Вас моноблок получается.. нехорошо.. 

ага.

не могли бы вы изменить код приведенный выше, так, чтоб в нем небыло ничего лишнего? т.к. я не очень понимаю что именно я должен сделать..

Добавлено через 1 минуту и 20 секунд
по последнему: вроде понял..

Добавлено через 3 минуты и 2 секунды
Цитата(boostcoder @  28.10.2010,  09:51 Найти цитируемый пост)
код приведенный выше, так, чтоб в нем небыло ничего лишнего?

т.е. мой код.
PM WWW   Вверх
mes
Дата 28.10.2010, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  28.10.2010,  08:51 Найти цитируемый пост)
не могли бы вы изменить код приведенный выше, так, чтоб в нем небыло ничего лишнего? т.к. я не очень понимаю что именно я должен сделать..


Цитата(mes @  28.10.2010,  08:17 Найти цитируемый пост)
пока оставим сервер в покое.. принимает - молодец, с него пока хватит.. 

Цитата(mes @  28.10.2010,  08:17 Найти цитируемый пост)
фактически только реализовать сендер и привязку.. 

 smile 


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1224 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.