Форум программистов
 
Расширенный поиск
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

Восстановить пароль
Повторная активизация e-mail



Ответ
 
Опции темы
Старый 25.12.2016, 17:02   #1
Aoizora
Пользователь
 
Регистрация: 11.11.2016
Сообщений: 24
Репутация: 10
По умолчанию Разработка своего сетевого протокола

Пишу несложный сетевой протокол. Мне нужно, чтобы приходящие пакеты в зависимости от значения некоторого поля выводились либо в консоль, либо добавлялись в конец файла, который может создаваться с рандомным именем каждый раз, когда происходит соединение. Какой паттерн проектирования для этого использовать? Пытаюсь прикрутить шаблон стейтмашин, но получается неоптимально: когда нужно сбрасывать нагрузку пакета в конец файла, приходится этот файл открывать каждый раз, когда приходит пакет данного типа. Поток пакетов может быть неоднородным, т.е. друг за другом приходят пакеты, содержимое которых надо записывать в разные места.

Вот что я написал сейчас:

Код:

#ifndef NETWORK_H
#define NETWORK_H
#include <Windows.h>
#include <stdio.h>
#include "packet.h"
class State
{
public:
    virtual int recv(SOCKET sock) = 0;
    virtual int send(SOCKET sock, char *data, size_t len) = 0;
};
class ConsoleState : public State
{
public:
    int recv(SOCKET sock);
    int send(SOCKET sock, char *data, size_t len);
};
class FileState : public State
{
    HANDLE hFile;
public:
    FileState();
    ~FileState();
    int recv(SOCKET sock);
    int send(SOCKET sock, char *data, size_t len);
};
class Network
{
    SOCKET sock;
    State *state;
    static int last_state;
public:
    Network();
    Network(SOCKET s) : sock(s), state(nullptr) {}
    void set_state(State *s)
    {
        delete state;
        state = s;
    }
    int send(char *data, size_t len);
    int recv();
};
#endif

Код:

#include "network.h"
int ConsoleState::recv(SOCKET sock)
{
    char buffer[200] = { 0 };
    int ret = ::recv(sock, buffer, 200, 0);
    printf("recieved : %s\n", buffer);
    return ret;
}
int ConsoleState::send(SOCKET sock, char *data, size_t len)
{
    packet header = { 0 };
    header.command = CMD_WRITE_CONSOLE;
    header.type_of_data = TYPE_ASCII_TEXT;
    header.size_of_data = len;
    ::send(sock, reinterpret_cast<char *>(&header), sizeof(header), 0);
    int ret = ::send(sock, data, len, 0);
    return ret;
}
FileState::FileState()
{
    hFile = CreateFile(TEXT("log.txt"),
        GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
}
FileState::~FileState()
{
    CloseHandle(hFile);
}
int FileState::recv(SOCKET sock)
{
    char buffer[200];
    DWORD bytes_read = 0;
    DWORD bytes_written = 0;
    bytes_read = ::recv(sock, buffer, 200, 0);
    printf("recieved %d bytes\n", bytes_read);
    WriteFile(hFile, buffer, bytes_read, &bytes_written, NULL);
    return bytes_read;
}
int Network::last_state = 0;
int FileState::send(SOCKET sock, char *data, size_t len)
{
    return 0;
}
int Network::send(char *data, size_t len)
{
    int ret = state->send(sock, data, len);
    return ret;
}
int Network::recv()
{
    packet header;
    ::recv(sock, reinterpret_cast<char *>(&header), sizeof(header), 0);
    if (last_state != header.command)
    {
        last_state = header.command;
        switch(header.command)
        {
        case CMD_WRITE_CONSOLE:
            set_state(new ConsoleState);
            break;
        case CMD_WRITE_FILE:
            set_state(new FileState);
            break;
        }
    }
    return state->recv(sock);
}

Сейчас работает запись в консоль или в файл в зависимости от пакетов, но проблем нет только тогда, когда приходят пакеты одного типа. Если приходят пакеты разного типа, но файл перезаписывается, например, когда происходит смена состояния. Это не то, что я хочу.

Плохо и то, что на каждый пакет открывается/закрывается файл. Еще и запись попакетная.

Нужно предусмотреть и обработку ошибок в пакетах. Как это сделать?
Aoizora вне форума   Ответить с цитированием
Ответ



Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна не большая разработка написание сетевого сканера ceo. orbita77771 Фриланс 0 08.04.2015 15:52
Разработка сетевого приложения "Пятнашки" на Си для Linux dasha1711 Помощь студентам 0 23.11.2012 21:28
Исследование протокола m1kx Безопасность, Шифрование 3 28.08.2012 12:53
Как автоматически прописать найстройки TCP|IP протокола для сетевого подключения? Человек_Борща Операционные системы общие вопросы 2 30.11.2011 01:06
Разработка протокола OrdJONY Проектирование web интерфейсов, приложений, базы данных 2 04.10.2007 13:21




16:53.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.

Покупайте на сайте www.skinon.ru уникальные чехлы и наклейки для телефонов.
таргетированный трафик


как улучшить посещаемость, а также решения по монетизации сайтов, видео и приложений

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru