ПрограммированиеФорумСеть

Winsock2, С++, не могу получить адрес отправителя (2 стр)

Страницы: 1 2 3 4 5 Следующая »
#15
21:29, 12 мая 2018

Ramm
> Я на шарпе делал так: я конвертировал в цикле нужные мне дробные, целые и
> прочие символы в массивы байтов,

Это называется сериализация и даже на С# есть более удобные способы

Ramm
> Вот только cout << c2 << endl выдает какую-то фигню, типа кракозябр. Ну да,
> блин, он думает там символы лежат. А как байты увидеть?=)

Он не только фигню выдаёт, но ещё и не знает, где остановиться,  - очевидно ваши знания С/С++ на низком уровне очень средненькие. Нужно, хотя бы, K&R почитать (там не очень много)

Ramm
> union - немного не то

Не то что бы не то, а совсем не то. Наиболее близкое к тому, - это структуры, но нужно понимать, что может отличаться порядок байт в зависимости от платформы и размер структуры в зависимости от настроек компилятора... поэтому используют специальные библиотеки, типа flatbuffers или ZeroMQ

#16
8:33, 13 мая 2018

Спасибо большое!
Не стоило, конечно, все так расписывать... Я не очень маленький тупой, наверное=) Перегрузка операторов есть не только в плюсах. Смешивание printf и cout произошло из-за копирования примера с msdn, при этом я не люблю printf, использую cout, исправлять printf-ы - лень.
Delfigamer
> Если у тебя никак не хватает внимательности расставить пробелы одинаково -
В VS Ctrl+K и затем Ctrl+D восстанавливает форматирование, но я торопился.
Delfigamer
> Если нужна копия в массив, лучше вместо &c2 записать просто c2.
Да, амперсанд там лишний...
Zab
> TCP гарантирует только что байты придут в той же последовательности, в которой
> ты их отправлял. Какими группами они придут - как получится.
Delfigamer
> Таким образом, при работе по сети, на места разрезов в TCP-пакетах полагаться
> нельзя.
Ok. Я был не прав.
Delfigamer
> union становится верным и гибким инструментом.
Очень интересная штука, но возникла пара вопросов.

  int i = 255;
  char c2[4];
  memcpy_s(c2, 4, &i, sizeof(int));

  int a2;
  memcpy_s(&a2, sizeof(int), c2, 4);
  cout << a2 << endl;


  union u
  {
    unsigned char bytes[4];
    int value;
  };
  u p;
  p.value = i;

  for (int z = 0; z < 4; z++)
  {
    cout << (int)c2[z] << " ";
  }
  cout << endl;

  for (int i3 = 0; i3 < 4; i3++)
  {
    cout << (int)p.bytes[i3] << " ";
  }
  cout << endl;

Одно и то же число при байтовом выводе в случае с копированием памяти и объединением выглядит по-разному.
255 в случае с memcpy_s выглядит как -1 0 0 0, а в bytes union: 255 0 0 0 (при переводе в char[])
1. Почему так происходит?
2. Какую форму лучше использовать для передачи чисел по сети? Прогонять их через объединение или копирование памяти с дальнейшим получением массивов char?
3. union u перестанет существовать сразу после выхода из функции и память освободится?

0iStalker
> Он не только фигню выдаёт, но ещё и не знает, где остановиться
Я забыл про окончание строки.
0iStalker
> Не то что бы не то, а совсем не то. Наиболее близкое к тому, - это структуры,
> но нужно понимать, что может отличаться порядок байт в зависимости от платформы
> и размер структуры в зависимости от настроек компилятора... поэтому используют
> специальные библиотеки, типа flatbuffers или ZeroMQ
Т.е. запись одного и того же числа в разных ОС в случае с union может выдать разный результат?

#17
9:43, 13 мая 2018

Ramm
Надеюсь, в твоем случае это не так, но многие шарп- и ява-программисты в принципе не могут освоить C++.
Осваивайся поскорей с этим языком. Или же выясняй что это не твое.
Быстро оно не осваивается. Ориентировочно, год нужен, чтобы перестать косячить, даже если у человека с направленностью мозгов все хорошо и опыт на других языках имеется.
Рано ты за сеть взялся, другие у тебя проблемы...

#18
9:47, 13 мая 2018

Ramm
> Я забыл про окончание строки.
Вот это "забыл" на C++ недопустимо совершенно. Никто ж тебя не поправит и не предупредит. И на первый взгляд может даже казаться что работает, пусть не в этом случае, но в других подобных. А потом все падает в непредсказуемых местах, даже напрямую с ошибкой не связанных, по контексту не найдешь.

#19
10:06, 13 мая 2018

Zab
> Осваивайся поскорей с этим языком.
Ну вот пока я ж пока не сильно облажался, какие-то фундаментальные вещи не спутал...=)
И все-таки, почему memcpy и union разный результат выдают... Да и откуда -1 появляется... Как char вообще может быть -1? По идее, мне как бы без разницы, если union на разных системах может выдать разный порядок char-ов, то формировать массив байтов-char-oв нужно с помощью memcpy, наверное.
Можно, если использовать union, при получении проверять, например, для теста отправлять определенное число, например 255. И если сервер при получении собирает из 4 charов число, а оно не 255, по поменять порядок байтов на противоположный. Это если я правильно понял идею, что в некоторых системах int 255 может выглядеть как 0 0 0 255, а не 255 0 0 0...

Удивительное рядом, но в случае с union char [0, 255], а вне union char [-128, 127]... И вот как быть в таком случае, и как поведет попытка приведения из char-ов одного типа в другой на другой машине, можно ли как-то явно указать какой тип использовать?

Все блин, сам дурак, во-первых CHAR_MAX и CHAR_MIN.
Во-вторых я ж написал unsigned char bytes[4].

#20
10:41, 13 мая 2018

Ну блин.
char - int8_t, без проблем может быть отрицательным.
Порядок байт внтури int зависит от архитектуры.(может быть вообще любым)
union/struct без #pragma pack(push,1) это одно сплошное западло
формат внутри float/double на разных архитектурах известен лишь богам.
Белые люди используют для упаковки спец-библиотеки типа protobuf/flatbuffers которые есть почти подо все. Очень экономит время, и дает возможность добавлять поля без поломки протокола.

#21
10:49, 13 мая 2018

ShadowTeolog
> формат внутри float/double на разных архитектурах известен лишь богам.
Это если я на клиенте запакую int или float в 4 char-a, а на сервере, который написан на .net framework (C#) попробую эти 4 байта привести к int или float соответственно, то не факт, что выйдет все верно?
Или же отличие только в Windows-UNIX?

#22
11:06, 13 мая 2018

Ramm
> Ну вот пока я ж пока не сильно облажался, какие-то фундаментальные вещи не спутал...=)
Сильно облажался, на самом деле. Если ты написал нечто подобное в одном месте и тебя ничто не кольнуло, наверняка подобного качества код еще во многих десятках мест. Это значит что работать не будет ничего и концов не найдешь.
На C++ ты обязан представлять как комп будет выполнять все тобой написанное. Это ж современный ассемблер, по сути, ты от нижнего уровня не изолирован, хотя и можешь строить абстракции. "Попробовал - получилось" тут не работает, это не прикладной язык. Надо очень много знать, чтобы на нем программировать.
Это все выводы по попыткам напечатать строку без нуля на конце.

А твое ожидание наличия сборщика мусора - это как раз фундаментальное (Честно говоря, я не обратил на это внимание).

На C++ то простые вещи не делаются, сейчас не двухтысячный год, когда на C++ пытались писать все. Дорого слишком, если что-то может быть без извратов написано с использованием других инструментов, оно другими инструментами и делается. Работа обычно коллективная, а тебя нельзя пускать в коллективный проект пока, вообще все разрушишь.
Не удивляйся, если услышишь отзывы типа "ошибка в ДНК", мы тут от этого удерживаемся, потому как оно не продуктивно, другие могут не удержаться. Если им поручили работать с тобой прямо сейчас - продуктивный выход у них один - от тебя избавиться, а мы тут просто болтаем, для нас не проблема, если ты выйдешь на необходимый для работы уровень через много-много лет, если вообще выйдешь.

#23
11:32, 13 мая 2018

Zab
> Сильно облажался, на самом деле
Ну хорошо, пусть будет так... Но я исправлюсь. Я даже к проекту не прикасался, просто смотрю, записываю только тестовые примеры.

Zab
> Не удивляйся, если услышишь отзывы типа "ошибка в ДНК", мы тут от этого
> удерживаемся, потому как оно не продуктивно, другие могут не удержаться. Если
> им поручили работать с тобой прямо сейчас - продуктивный выход у них один - от
> тебя избавиться, а мы тут просто болтаем, для нас не проблема, если ты выйдешь
> на необходимый для работы уровень через много-много лет, если вообще выйдешь.
Это дикий оффтоп, но в настоящий момент вот эта тема с сетью, особенно на плюсах, для меня чисто хобби.

Zab
> На C++ то простые вещи не делаются, сейчас не двухтысячный год, когда на C++ пытались писать все.
Если бы можно было к проекту на С++ подрубить net framework, и писать хотя бы на "диалекте" (CLR), вообще все было бы в шоколаде.
Но так делать нельзя...

Как же все-таки правильно переводить float-int-double в char для передачи через сокеты? Вот как ты переводишь?

#24
12:02, 13 мая 2018

Ramm
> Если бы можно было к проекту на С++ подрубить net framework, и писать хотя бы
> на "диалекте" (CLR), вообще все было бы в шоколаде.
> Но так делать нельзя...
Можно, на самом деле.
Способ первый - managed С. Изврат полный, до тошноты, но можно.
Способ второй - обернуть весь твой код на C++ в COM и подключить к дотнету. Тоже не очень хорошо, не безопасно. Дотнет тебе не даст сделать особенных гадостей, а на C++ грязными ручками можешь сделать все что угодно. И ведь сделаешь же... Требования к квалификации программиста на C++ на несколько порядков выше.

> Как же все-таки правильно переводить float-int-double в char для передачи через сокеты? Вот как ты переводишь?
Два способа:
1. Через текстовый формат.
2. Специфицировать для себя один из двоичных форматов и считать конвертацию из него и в него проблемой тех, у кого аппаратная платформа представляет числа иначе.
На самом деле, хоть и считается что могут быть разные форматы, де-факто они сейчас везде одинаковые. Не из-за того, что это требуют, а просто удобный формат разработали, который все передирают и не считают необходимым изобретать велосипед. Компы, которые хранили в других форматах, такие были лет 15 назад, давно ушли в историю.

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

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

> в настоящий момент вот эта тема с сетью, особенно на плюсах, для меня чисто хобби.
Ну и отлично... Не на живых же людях тренироваться... Как-то опыт надо получать, вот ты его и получаешь.
Хотел только предупредить, если ты со своим нынешним уровнем сунешься в реальный проект, ничего кроме оскорблений не получишь.
А так... никого не подводишь, делаешь что душа пожелает...

#25
12:16, 13 мая 2018

Zab
> 1. Через текстовый формат.
Это передача 3.14, 4, 3.6789456 в виде строки "3.14/4/3.6789456", например? Ну, это вариант, но вариант печальный...
Zab
> 2. Специфицировать для себя один из двоичных форматов и считать конвертацию из
> него и в него проблемой тех, у кого аппаратная платформа представляет числа
> иначе.
Ну это через union или memcpy, например? Если да, то в пределах windows формат одинаковый? Или я неверно понял фразу "один из двоичных форматов"?

#26
12:24, 13 мая 2018

Ramm
> в пределах windows формат одинаковый?
Он не обязан быть одинаковым.
Но задача упрощается тем, что он таки одинаковый. Никто этого не обещал, но по факту одинаковый. На сегодняшний момент. Завтра может все измениться. Или на какую-нибудь экзотику наткнешься.
Это касается плавающей точки. Инты могут иметь разную длину и разный порядок байт, их для сети специфицируют, никогда не посылают просто int.

#27
12:28, 13 мая 2018

Тебе не обязательно формировать байтовый массив для отправки по сети. Можешь заполнить сишную структуру, взять на нее указатель, приказать считать его байтовым и отправить. На С++ ты можешь игнорировать типизацию, если того хочешь. Ты вообще все что угодно можешь делать, язык в себе дисциплины не несет, дисциплина должна быть у тебя в голове.

#28
12:37, 13 мая 2018

Ramm
> Если да, то в пределах windows формат одинаковый?

Для флоатпойнтов - да, это стандарт IEEE 754

#29
13:20, 13 мая 2018

Zab
> Можешь заполнить сишную структуру, взять на нее указатель, приказать считать
> его байтовым и отправить. На С++ ты можешь игнорировать типизацию, если того
> хочешь.
Т.е. с помощью memcpy я заталкиваю структуру со своими интами и флоатами в массив char, отправляю его, а на той стороне (например, это UDP-пакет) разворачиваю обратно в такую же структуру? И все корректно прочитается?
Но проблема с интами все равно останется? Так? Т.е. не факт, что они корректно восстановятся?
ZeroCool++
> Для флоатпойнтов - да, это стандарт IEEE 754
С флоатами такой проблемы, как порядок байтов, быть не может? Завернул через memcpy в 4 char-а, а на другой виндовс-машине развернул, и все должно работать корректно? Так я могу все числа, те же int, переводить во флоат, типа 675 в 675.0, а на том конце округлять до целого.

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеФорумСеть

Тема в архиве.