Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.01.2010, 00:36   #1
olik83
Пользователь
 
Регистрация: 20.09.2009
Сообщений: 17
Вопрос протокол для мессенджера.

пишу инстант-мессенджер простенький,
ну там прием отправка сообщений,пока без файлов, смайлов и всяких статусов.
и вот встала задача написать протокол.
решила реализовать его в виде двух классов данные и сам протокол у которого будет как бы хиддер и тело, состоящее из объекта класса Data
застряла на методе createPacket, прям ступор... т.е. лучше енум этот привести в свитче в самом методе или???
и вот еще статические поля можно же только в статических методах вызывать, как бы мне тогда ID пакета запихнуть в криейт.
вобщем требуются как воздух ваши идеи и советы, а я уж их как-нибудь пропишу.
и вот еще один вопрос, а в этом протоколе реально ли с обычными данными работать или их надо как-то в бинарном виде???
айнидхелп.

з.ы. в идеале, ну по кр мере как я представляю себе все это дело, у меня будет еще класс отдельный обработчик событий, класс обработчик сообщений который будет использовать протокол, ну и классы ресиверы и сендеры.
Код:
#include "Socket.h"
#include "Data.h"

//#include <stdlib>
#include <iostream>
#include <string>

#ifndef PACKET_H
#define PACKET_H

class Packet
{
    int _packetsize;
    static int _packetID;
    Data data;
    int type;
    enum PACKET_TYPES
    {STATE_PACKET=0,REGISTR_PACKET,LOGIN_PACKET,LOGOUT_PACKET,SENDMESS_PACK,DELUSR_PACKET,ADDUSR_PACKET};
  protected:
    static int getPacketID(){return _packetID;}
  public:
    Packet();
    ~Packet(){};
    void createPacket();
    //void deletePacket();
    Packet& getPacket() {return *this;};
    int getSizePacket();  
};

#endif

int Packet::getSizePacket()
{
  _packetsize=+data.getDatasize();
  return _packetsize;
}  

void Packet::createPacket()
{
  _packetsize=_packetsize.getSizePacket();
  
  switch()
}
Код:
#ifndef DATA_H
#define DATA_H

class Data
{
    enum DATA_TYPES {STRING,INT};
    int _datasize;
    static int _toUID;
    static int _fromUID;
  protected:
    static int getToUID();
    static int getFromUID();
  public:
    Data(){};
    ~Data(){};
    //void sendData();
    void getData();
    inline int getDatasize() {return _datasize;}    
}
#endif
olik83 вне форума Ответить с цитированием
Старый 04.01.2010, 10:38   #2
olik83
Пользователь
 
Регистрация: 20.09.2009
Сообщений: 17
По умолчанию

откажите))
а что вы хотите увидеть в моем коде если я только начала писать протокол и не совсем понимаю как это делать.
olik83 вне форума Ответить с цитированием
Старый 04.01.2010, 12:21   #3
olik83
Пользователь
 
Регистрация: 20.09.2009
Сообщений: 17
По умолчанию

это программа учебная да, но она не универовская. можно так сказать, для себя разбираюсь в большей степени.
опыта да, нет. я занимаюсь си++ месяца три от силы, ну четвертый пошел.
т.е. вы раздаете советы только опытным программистам?)) ну и на том спасибо.
olik83 вне форума Ответить с цитированием
Старый 04.01.2010, 12:57   #4
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Протокол в исконном значении - это способ связи между разными уровнями приложений.
Написать низкоуровневый протокол - имхо, вам такое не нужно. Вам просто нужно создать определенные правила формирования пакетов, чтобы вам было удобно их парсить на стороне клиента и сервера.
Для начала определите для себя типы пакетов.
Например:
DATA_PACKET - пакет с данными типа сообщения и прочее
SIZE_PACKET - служебный пакет, который приходит перед пакетом с данными, чтобы обозначить его размер (ну если пакет будет большой)
LOGIN_PACKET - пакет входа в сеть.
Аналогично логину сделайте LOGOUT_PACKET
Это примерный набор. Какие пакеты вам нужны - решать вам.
Шаг следующий
Определите структуру пакета. Структура должна быть удобной для парсинга. То есть, чтобы на разбор пакета не уходило много времени.
Далее описываете класс пакета, если у разных пакетов разная структура - наследуете от базового класса PACKET нужные данные и получаете все разнообразие пакетов, которое вам нужно.
Цитата:
как бы мне тогда ID пакета запихнуть в криейт
Сделайте статический счетчик пакетов. При создании очередного пакета просто увеличивайте счетчик.
Выглядеть это будет примерно так
Код:
class BASE_PACKET
{
    public:
        BASE_PACKET(...)
        {
            packet_counter++;
            this->id = packet_counter;
        }
        ...
    private:
        static int packet_counter;
        unsigned int id;
};
...
//где-то в другом файле
int BASE_PACKET::packet_counter = 0;
Цитата:
у меня будет еще класс отдельный обработчик событий
Вам нужен класс, который эти события будет генерировать. Это уже нужно связать с сокетами. Почитайте про асинхронные сокеты и мультиплексирование ввода/вывода.
Если будут вопросы по сокетам и мультиплексированию - пишите мне в ЛС, я все объясню. Удачи.
MaTBeu вне форума Ответить с цитированием
Старый 04.01.2010, 20:01   #5
olik83
Пользователь
 
Регистрация: 20.09.2009
Сообщений: 17
Вопрос

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

кода много, за основу взяла абстрактную фабрику

Код:
#include "PacketHeader.h"
#include "PacketData.h"

#ifndef _PACKET_FACTORY_H_
#define _PACKET_FACTORY_H_

class PacketFactory
{
    static int _packetCounter;
    unsigned int _packetID;
  public:
    PacketFactory()
    {
      _packetCounter+=_packetCounter;
            this->_packetID = _packetCounter;
    }
    //virtual ~PacketFactory(){};
    virtual void createPacket(PacketHeader&,PacketData&)=0;
    virtual PacketFactory& getPacket()=0;
    virtual int getSizePacket()=0;
    int getPacketID(){ return _packetID;}
};  
    
#endif
Код:
#include "PacketFactory.h"
#include "PacketHeader.h"
#include "PacketData.h"

#include <iostream>
#include <string>
#include <map>

#ifndef _PACKET_H_
#define _PACKET_H_

class Packet:public PacketFactory
{
    int size;
    std::string data;    
    unsigned int _packetID;
  public:
    Packet();
    void createPacket(PacketHeader&,PacketData&);
    Packet& getPacket(){return *this;}
    int getSizePacket();
    int getPacketID(){ return _packetID;}  
    typedef std::map<PacketHeader,PacketData> IdMapType;
    IdMapType idMap;    
};

#endif
---packet.cpp

#include "Packet.h"

#include <map>
#include <string>
#include <iostream>

Packet::Packet():PacketFactory()
{
  /*idMap[Packet::PacketCreate] = Packet<PacketCreate>;*/
}

Packet& createPacket(PacketHeader &ph, PacketData &pd)
{
  size=ph.size;
  data=pd.getData();

  map<ph.type,pd.str>::iterator mapping = idMap.find(this->_packetID);

 return mapping->second();
}
 
 int Packet::getSizePacket(PacketHeader &ph)
 {
   int temp=ph.getSize();
   return temp;
 }
Код:
#include <iostream>
#include <string>

#ifndef _PACKET_TYPE_H
#define _PACKET_TYPE_H

struct PacketType
{
  enum _types
     {STATE_PACKET=0,REGISTR_PACKET,LOGIN_PACKET,LOGOUT_PACKET,SENDMESS_PACKET,DELUSR_PACKET,ADDUSR_PACKET} type;
  int getPacketType();
};

int PacketType::getPacketType()
{
  switch(type)
  {
    case STATE_PACKET:   
         return 0; break;
    case REGISTR_PACKET: 
         return 1; break;
    case LOGIN_PACKET: 
         return 2; break;
    case LOGOUT_PACKET:
         return 3; break;
    case SENDMESS_PACKET: 
         return 4; break;
    case DELUSR_PACKET: 
         return 5; break;
    case ADDUSR_PACKET:  
         return 6; break;
    default: return -1; break;
  }
}

#endif
Код:
#include <string>

#ifndef _PACKET_DATA_H
#define _PACKET_DATA_H

class PacketData
{
    int size;
    std::string str;
  public:
    std::string getData(){return str;}
    int getPacketSize(){return size;}
};
    
#endif
Код:
#include <iostream>

#include "PacketType.h"
#include "PacketData.h"

#ifndef _PACKET_HEADER_H
#define _PACKET_HEADER_H

class PacketHeader
{
    int type;
    int size;
  public:
    PacketHeader()
    {
      type=0;
      size=0;
    }
    PacketHeader& getType(PacketType&);
    PacketHeader& getSize(PacketData&);
};

#endif

---packetheader.cpp
#include "PacketHeader.h"

PacketHeader& PacketHeader::getType(PacketType &pt)
{
    type=pt.getPacketType(); 
    return *this;
}

PacketHeader& PacketHeader::getSize(PacketData &pd)
{
  size=pd.getPacketSize();
  return *this;
}
olik83 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
MultiPart Протокол и MJPEG BleStaR Общие вопросы C/C++ 0 03.12.2009 19:48
протокол блокировки таблицы Bat{CMD}_Men БД в Delphi 4 16.10.2009 17:36
Протокол футбольного матча ZDN Microsoft Office Excel 1 21.04.2008 18:50