|
Модераторы: feodorv |
|
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
Всем привет. Прошу объяснить все в подробностях для дурака.
Такая задача стоит. Есть TCP сервер и клиент. Клиент присылает серверу сообщение msgCli, в котором первый байт - команда серверу (например, 0х15), затем 5 байт - ASCII строка с "\0". Сервер в ответ отправляет сообщение msgServ: 1й байт - команда (например, 0х45), 2й байт - команда (например, 0х42),затем 3 байта ASCII строка с "\0", затем 9 байт сообщение. Эти 9 байт получаются следующим образом:
Теперь перед отправкой мы должны отобразить на экранmsgRand в ASCII, а отправить в десятичном виде, т.е. на экран вот в таком виде показываем - 4da234f199a5bce8c1, а отправляем - 7716252241153165188232193 (данные значения взяты просто для примера). Собственно я не могу сообразить как msgRand перевести в эти два представления. Потом собрать две команды по 1 байту, ASCII строку, считанные 9 байт в одно сообщение и отправить. P.S. Это не лабораторка. Просто учусь программировать. Хотелось бы разобраться с этим. Использую Ubuntu 14.04 + QtCreator(Qt 4.7). |
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Я запутался.
и никак друг с другом не сочетаются. Откуда тогда у Вас пример для 4da234f199a5bce8c1 => 7716252241153165188232193? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
_zorn_ |
|
|||
Эксперт Профиль Группа: Завсегдатай Сообщений: 1077 Регистрация: 21.8.2007 Репутация: нет Всего: 12 |
Есть такое подозрение, что школьник хочет замутить свой ботнет. С блекджеком соответственно.
|
|||
|
||||
nullpoint |
|
||||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
_zorn_, да не нужен мне ботнет, тем более с моими навыками я его буду писать лет 100:)
feodorv, про десятичный вид я скорее всего неправильно выразился.
Считал из /dev/random 9 байт, затем вывел:
"Интовое" представление нужно записать в базу данных, чтобы при следующем запуске приложения, если не были считаны новые 9 байт, отобразить на экран и отправить клиенту предыдущее значение. Это сообщение отредактировал(а) nullpoint - 1.8.2014, 21:28 |
||||
|
|||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Вот не за что не догадался бы))) "Интовое" представление не однозначное, восстановить из него однозначно первоначальные 9 байт, скорее всего, не удастся, если не потребовать 3 "интовых" символа на один первоначальный. Но, честно говоря, я не вижу вообще никаких предпосылок для того, чтобы по сети гонять, а затем сохранять в базе, именно "интовое" представление в противовес оригинальному, девятибайтовому. Вы всегда можете сделать что-то в этом роде:
Особого смысла в этом нет, но дело Ваше))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
feodorv, подскажите тогда как правильно сделать. Как это все передать одним сообщением "1й байт(0x45)2й байт(0x42)3 байта(ASCII с \0)9 байт(msgRand)"? И как принять от клиента сообщение и разобрать его на части?
Можно же вроде вот так сделать:
И записать это в два поля БД, но вот как потом это все обратно восстановить в единое целое? Это сообщение отредактировал(а) nullpoint - 1.8.2014, 22:58 |
|||
|
||||
feodorv |
|
||||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Как обычно:
Здесь немного сложнее, так как целостное 14-байтовое сообщение может быть разбито протоколом TCP (что маловероятно, но возможно) на несколько пакетов, которые читаются отдельными recv:
Аналогично:
Девятый байт пропал. Или он не нужен? Вроде, у баз данных должен быть тип поля "сырые данные", в которое можно запихнуть произвольные данные заданной длинны. Да и текстовое поле (длинной 9 символов) у некоторых БД позволяет хранить произвольные символы, не только отображаемые на экране. Ну и в крайнем случае храните эти 9 символов в 16-ричном виде в текстовом поле длины 18, из 16-ричного вида всегда можно восстановить исходный 9-байтовый вид... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
feodorv, я жутко извиняюсь, не объяснил все до конца, поэтому и возникла небольшая путаница. :(
Считывая из /dev/random, я таким образом генерирую ключ для клиента, т.е. мне как раз таки не нужны "сырые" байты, а нужно случайно сгенерированное число. Т.е. считанные байты я перевожу в unsigned int (7716252241153165188232193) и его отправляю клиенту, а на экран я должен вывести этот ключ в виде ASCII (4da234f199a5bce8c1). И вот тут у меня начинаются проблемы. Точно, даже не обратил внимания, что только 8 байт записал. Я имел в виду что строка ASCII с завершающим \0, а не вся она состоит из \0 т.е. "abc\0" |
|||
|
||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
||||
|
||||
feodorv |
|
||||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Это сильно меняет ситуацию? Ну будет сообщение длиной 15 байт...
Всё равно не понятно, что Вам нужно. Хотите гонять "интовый" вид своих 9 байт - гоняйте, я не настаиваю, хотя этот самый "интовый" вид можно получить и на стороне клиента из сырых 9 байт. Делайте, как Вам угодно. Только тогда в формат сообщения Вы должны будете добавить длину сообщения, так как "интовое" представление не обладает фиксированной длиной (в отличие от сырого вида) (либо хитрый однократный обмен сообщениями с правильными shutdown( socket, SD_SEND)). Да и о "случайности" в таком виде можно говорить лишь условно. Как получить "интовую" строчку я уже писал: Аналогично получается "шестнадцатиричная" строка:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
feodorv, да я совсем запутался с этими вещами и поэтому не могу нормально объяснить, что нужно...
Давайте я опишу лучше какую я задачу поставил себе, а вы подскажите как бы вы ее решили. Наверное, так будет лучше. Клиент присылает серверу команду (или 0х45, или 0х44) и ASCII строку с завершающим \0, каждый клиент присылает свою строку, которая не меняется, своего рода идентификатор. Сервер смотрит какую команду прислал клиент и в зависимости от команды или высылает ответ (если 0х45) или выводит на экран сообщение (если 0х44). В ответ клиенту он отсылает команду 0х45, команду 0х42, ASCII строку с \0 (3 байта), ключ (9 байт). Когда сервер принял сообщение и "увидел" что команда равна 0х45, он начинает искать в базе присланную ASCII строку, если нашел, то генерирует ключ 9 байт, отображает его на экран в виде ASCII кодов, т.е. выводит 18 символов 4da234f199a5bce8c1, и затем отправляет ключ клиенту в таком виде 0х450х42abc\07716252241153165188232193. Перед отправкой ключ записывается в БД, чтобы при следующем запуске программы, если не сгенерирован новый ключ отправить его клиенту и вывести на экран в ASCII. |
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Итак, имеем однократный обмен сообщениями.
сервер При подключении клиента сервер делает recv на 5(???) байт, которые клиент обязан прислать в течении некоторого времени (если не прислал, соединение сервером закрывается). По получении этих 5 байт сервер делает:
клиент Подключается к серверу и шлёт 5-ти байтовый запрос. Если запрос с командой 0х45, то ждёт ответа неопределенной длины с ключом. Так? Зачем клиенту "интовое" представление? Что он будет с ним делать? В чем сложность? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
Просто выводим сообщение об ошибке. Если нашли то отсылаем клиенту ключ из БД. Лучше наверное сначала сгенерировать ключ и записать его в БД и уже потом брать его оттуда и отправлять. А новый ключ генерировать по какому-нибудь другому событию (это не главное). Неважно, любое. Можно написать что ошибка клиента. Ничего не делать, ну или можно вывести сообщение об ошибке. Это значит мои непонятки пошли. Я думал что если мы отсылаем ключ, то это должно быть какое-то значение, а не непонятный набор печатных и непечатных символов. Как записать ключ в базу. Запросы я могу сделать. Проблема в том в каком виде он туда запишется и чтобы нормально его потом оттуда можно было взять. Как проверять есть ли в базе присланный клиентом идентификатор? Не буду же я последовательно каждый элемент массива сравнивать с символом строки идентификатора из базы. |
|||
|
||||
feodorv |
|
||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Тогда при каждом обращении клиента для него будет сгенерирован новый ключ. Вы этого добиваетесь? Ну почему непонятных. Это есть значение ключа. (Правда, гонять по сети ключ в незашифрованном виде уже не хорошо, ну да ладно))) Всё зависит от того, какую БД Вы хотите использовать. Для данной задачи вполне подойдет какая-нибудь btree, либо самописный текстовый файл, который грузится в бинарное дерево при старте сервера.
Это вопрос к БД. И даже в другую ветку Идентификатор клиента как ключевое поле? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
Нет. Ключ просто будет генерироваться независимо от того сколько раз клиент обратился. Новый ключ раз в сутки будет создаваться к примеру. Мне бы сначала просто отправить без шифрования:) MySQL Можете показать как это реализовать без записи в БД? Т.е. сгенерировали ключ, отобразили его на экран в ASCII, приняли от клиента сообщение, посмотрели по базе идентификатор, отправили клиенту сообщение или вывели сообщение об ошибке, если нет такого идентификатора. |
|||
|
||||
feodorv |
|
||||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Гм. Я не работаю с QtCreator, поэтому тупые BSD сокеты. Только сетевой обмен, остальное сами Клиент
Сервер
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
nullpoint |
|
|||
Шустрый Профиль Группа: Участник Сообщений: 51 Регистрация: 4.6.2013 Репутация: нет Всего: нет |
feodorv, спасибо, уже сам разобрался, но с помощью вашего кода подправил свое приложение
|
|||
|
||||
feodorv |
|
|||
Эксперт Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |