Вопрос № 55797: Здраствуйте уважаемые Эксперты, может быть немного не по теме, Вопрос такой, как можно средствами с++ скопировать структуру в строку, идея создания свой icq, проблема в инкапсуляции пересылаемых строк (кому, от кого, и что) я решил что можно создать ...Вопрос № 55842: Здравствуйте.
Я решил написать маленькую прожку, аналог диспетчера задач в Windows, но нигде не могу найти функции для вывода дерева процессов в C++builder 6.
Есть версия, что это аналог функций TaskFirst и TaskNext на Delphi.
П...Вопрос № 55843: Доброго времени суток. Я столкнулся с одной задачей, которая совершенно сбивает с толку.
В задаче необходимо реализовать связный список объектов классов, наследуемых от одного абстрактного класса. А именно, написать 2 функции : добавления нового...
Вопрос № 55.797
Здраствуйте уважаемые Эксперты, может быть немного не по теме, Вопрос такой, как можно средствами с++ скопировать структуру в строку, идея создания свой icq, проблема в инкапсуляции пересылаемых строк (кому, от кого, и что) я решил что можно создать структуру, а потом побайтно скопировать в строку и передать, а на сервере принять и восстановить в структуру, так легче будет работать, а если есть у кого какие идеи, поделитесь. Зарание СПАСИБО.
Отвечает: ADSota
Здравствуйте, Харламов Евгений Вячеславович!
Можно передавать структуру не изменяя ее. Сообщения редкие и тут траффик экономить неинтересно.
struct ISQmessage{
char UserFrom[8];
char UserTo[8];
char UserMSG[512];
}msg;
WriteFile(mysocket,msg,sizeof(ISQmessage));
--------- Открыть глаза навстречу солнцу
Ответ отправил: ADSota (статус: Специалист)
Ответ отправлен: 18.09.2006, 09:53 Оценка за ответ: 5
Отвечает: Sergijj
Здравствуйте, Харламов Евгений Вячеславович!
Скорее всего так прямо перевести структуру в строку и в таком виде отправить у Вас не выйдет. Точнее выйдет, но работать не будет. Возможные проблемы:
1. Нули и прочие binary и control символы в получившемся пакете.
2. Проблема разделения данных друг от друга.
3. Придётся данные передавать только в бинарном формате.
На мой взгляд варианта решения 2:
1. Если Вы хотите именно ASCIIZ формат данных, то Вы переводите всю структуру sprintf() в ASCIIZ, отделяя поля данных друг от друга каким-нибудь своим терминатором, например символом 0x03 (он хоть и управляющий, но мало где используется). А на другом конце разбираете (parse) строку по полям. Например так:
Уславливаемся, что поля будут иметь следующие значения:
1) "От кого"
2) Список "кому"
3) Штамп времени
4) Сама строка сообщения
5) Оканчивается всё это нуль-терминатором
6) Внутри структуры данные отделяются терминатором '#'
7) Внутри списка данные разделяются символом ','
При таком раскладе строка посланная юзером "Чайник" юзерам "Кофейник" и "Блюдце" будет выглядеть так:
Чайник#Кофейник,Блюдце#2134526426#Привет, Кофейник и Блюдце!
Я рад вас видеть!, где в поле "штамп времени" вставлено количество секунд, прошедших с ХХХХ года (ну например в *nix формате).
При этом если строка отправляется серверу (например для авторизации) поля могут иметь другие значения, например там может быть пароль авторизации и пр. нужная или управляющая контак-листом информация.
Вы видите, что это получилась обычная ASCIIZ строка, работать с которой удобно стандартными строковыми функциями поиска, сравнения, определения длины и пр. Единственные ограничения, которые возникают, это те, что внутри строки нельзя использовать (в этом примере) произвольно 3 символа: '#', ',', 'Этот способ хорош тем, что пролезет везде, легко переводится под другие протоколы передачи данных, имена юзеров, сообщений, пакетов ничем не ограничены (ограничены только длиной окна TCP/IP или RS-232, да и то только
в некоторых случаях...:)
2. Вариант 2 заключается в том, что данные Вы передаёте бинарно. Тогда необходимо создать бинарный же заголовок фиксированной длины (упомянутая Вами структура) со всей сопутствующей информацией внутри, где в том числе будет прописана и длина всего пакета.
Этот вариант хорош для своих целей (например в промышленных сетях), но для чата этот вариант IMHO не особенно подходит:
1) Придётся пользоваться одной неизменяемой структурой во _всех_ программных модулях.
2) Длина пакета будет фиксированой и ограниченой длиной внутреннего буфера (тогда как в первом варианте можно безболезненно разбивать сообщение на несколько пакетов и ждать завершающего нуля).
3) Имена юзеров будут либо жёстко лимитированы по длине, либо индексированы на сервере (при архитектуре клиент-сервер), а это - новые запорочки для поддержания базы данных.
4) Теряется гибкость протокола и совместимость "на ходу" с уже существующими протоколами передачи текстовой информации.
5) и т.д...
Простите, если не так понял вопрос, но уж как понял, так и ответил...:)
Успехов!
--------- Стучитесь! И Вас откопают...
Ответ отправил: Sergijj (статус: 5-ый класс)
Ответ отправлен: 18.09.2006, 10:17 Оценка за ответ: 4
Отвечает: Хватов Сергей
Здравствуйте, Харламов Евгений Вячеславович!
Формально проблем нет. Даже копировать не надо. Достаточно сделать cast-преобразование указателя на структуру в void* или char* , а длину узнать через sizeof(struct)
Только надо, чтобы двоичное представление данных было одинаковым у всех клиентов, что верно только если все они на одной платформе: машины одной архитектуры, одинаковые ОС и одинаковые компиляторы (и то можно поломать, например с помощью #pragma). Так что пересылать двоичную информацию по сети крайне нежелательно.
Ответ отправил: Хватов Сергей (статус: 4-ый класс)
Ответ отправлен: 18.09.2006, 12:34 Оценка за ответ: 4
Отвечает: Www2
Здравствуйте, Харламов Евгений Вячеславович!
Совет такой: закодировать двоичные данные, как это делается для почтовых вложений, то есть алгоритмом base64 или uu-кодированием. При этом двоичные данные будут представлены в виде строки состоящей только из ASCII-символов. На принимающей стороне раскодировать.
Можете поискать алгоритмы в интернете. Я даже когда-то скачивал две утилитки (uuencode и uudecode) с иходными текстами.
--------- Нет правил без исключений, правило без исключения - это исключение из правил.
Ответ отправил: Www2 (статус: 10-ый класс)
Ответ отправлен: 18.09.2006, 14:06 Оценка за ответ: 4
Вопрос № 55.842
Здравствуйте.
Я решил написать маленькую прожку, аналог диспетчера задач в Windows, но нигде не могу найти функции для вывода дерева процессов в C++builder 6.
Есть версия, что это аналог функций TaskFirst и TaskNext на Delphi.
Пожалуйста, пришлите их мне вместе с библиотекой... очень нужно.
Отвечает: n0name
Здравствуйте, Ustilkin Vladimir Vladimirovich!
В приложении.
Приложение:
Ответ отправил: n0name (статус: 5-ый класс)
Ответ отправлен: 18.09.2006, 14:36
Вопрос № 55.843
Доброго времени суток. Я столкнулся с одной задачей, которая совершенно сбивает с толку.
В задаче необходимо реализовать связный список объектов классов, наследуемых от одного абстрактного класса. А именно, написать 2 функции : добавления нового элемента списка и просмотра уже добавленных. По условию задачи эти функции должны быть чисто виртуальными и переопределёнными во всех классах потомках. Указатель на начало списка - статический указатель на базовый класс.
В процессе решения я написал код (см приложение), который по идее должен работать для всех классов потомков(т.е. виртуальность не нужна). Однако в задаче говорится именно о невозвожности правильного решения без использования виртуальности.
Приложение:
Отправлен: 18.09.2006, 14:46
Вопрос задал: Satas (статус: Посетитель)
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 10)
Отвечает: Melamed
Здравствуйте, Satas!
Правильно ругается. Абстрактные методы класса не могут быть реализованы в самом абстрактном
классе, а реализуются только в его потомках. См. Приложение
Приложение:
Ответ отправил: Melamed (статус: 5-ый класс)
Ответ отправлен: 18.09.2006, 15:04