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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2015, 15:11   #1
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию Передача Unicode строки по сокетам

Добрый день уважаемые программисты, пытаюсь реализовать клиент-сервер общение между серверам написанным на c++ с использованием boost и с# приложением, проблема заключается в том что при попытке декодировать массив байтов на стороне c# -> Encoding.Unicode.GetString я получаю знаки вопросов.

Вот таким образом я передаю строку:
Код:
std::wstring data = L"ПРИВЕТ МАЗАФАКА";
int length = data.length() * sizeof(wchar_t);
socket->write_some(boost::asio::buffer(data, length));
Вот таким образом я получаю строку
Код:
if (_networkStream == null)
{
 _networkStream = _tcpClient.GetStream();
}

var bytes = new byte[30];
_networkStream.Read(bytes, 0, 30);
var messageText = Encoding.Unicode.GetString(bytes, 0, 30);
Что собственно я делаю не так? Нуждаюсь в вашей помощи!

Последний раз редактировалось coNsept; 05.11.2015 в 15:24.
coNsept вне форума Ответить с цитированием
Старый 05.11.2015, 16:24   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я в таких случаях зарекся передавать открыто строку. Перекодировываю ее в Base64 или в URI и горя не знаю
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.11.2015, 16:32   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а asio::buffer точно нормально принимает wstring?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.11.2015, 17:47   #4
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Я думаю вы правы "Пепел Феникса", basic_string наверное не дружит с wstring.
Я не силен в плюсах, если не прав, подправьте.

Код:
template <typename Elem, typename Traits, typename Allocator>
inline const_buffers_1 buffer(
    const std::basic_string<Elem, Traits, Allocator>& data,
    std::size_t max_size_in_bytes)
{
  return const_buffers_1(
      const_buffer(data.data(),
        data.size() * sizeof(Elem) < max_size_in_bytes
        ? data.size() * sizeof(Elem) : max_size_in_bytes
#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
        , detail::buffer_debug_check<
            typename std::basic_string<Elem, Traits, Allocator>::const_iterator
          >(data.begin())
#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
        ));
}
Цитата:
Я в таких случаях зарекся передавать открыто строку. Перекодировываю ее в Base64 или в URI и горя не знаю
Stillet, то есть вы хотите сказать я могу спокойно кириллицу в std::string перекодировать в base64 и на шарпе ее без проблем поднять?

Последний раз редактировалось Stilet; 05.11.2015 в 18:53.
coNsept вне форума Ответить с цитированием
Старый 05.11.2015, 18:54   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
я могу спокойно кириллицу
И не только кириллицу
мефодиевицу тоже
Надо только уточнить как это правильно делать.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.11.2015, 20:23   #6
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Все таки, мне удалось подружить сервер и клиент с юникодом и даже через buffer.

Код:
void AcceptAsync(tcp::socket *socket)
{
 std::wstring messageText = L"привет, как дела?";

 int length = messageText.length() * sizeof(wchar_t);
 auto buffer = new char[4 + length];

 memcpy(buffer, &length, sizeof(int));
 memcpy(&buffer[4], &messageText[0], messageText.length() * sizeof(wchar_t));

 socket->write_some(boost::asio::buffer(buffer, 4 + length));

 delete[] buffer;
 buffer = nullptr;

 ConsoleManager::WriteLine(" > sent test string");
}
Код:
public static void ReceivePacket(TcpNetwork tcpNetwork, Action onReceive)
{
 var networkStream = tcpNetwork.GetNetowrkStream();

 while (tcpNetwork.Connected)
 {
  try
  {
   var header = new byte[TcpNetwork.HeaderLength];
   TcpNetwork.ReadPacket(networkStream, header);

   var length = BitConverter.ToInt32(header, 0);

   var content = new byte[length];
   TcpNetwork.ReadPacket(networkStream, content );

   var message = Encoding.Unicode.GetString(content);
  }
  catch (IOException ioex)
  {
  }
  catch (Exception ex)
  {
  }
 }
}
На выходе вижу нормальный текст и вот такой вот красивый массивчик: http://prntscr.com/904777

И тут я решил на этом не останавливаться и попробовать заполнить и передать структуру, но попытка не увенчалась успехом.
А сделал я собственно следующее но в итоге получаю на стороне шарпа совсем хамно: http://prntscr.com/9046gc

Код:
void AcceptAsync(tcp::socket *socket)
{
#pragma pack(push, 1)
 struct Handshake
 {
  int Length;
  wchar_t *Text;
};
#pragma pack(pop)

 Handshake handshake;

 handshake.Text = L"Привет, как дела?";
 handshake.Length = wcslen(handshake.Text) * sizeof(wchar_t);

 int length = 4 + handshake.Length;
	
 auto buffer = new char[length];
 memcpy(buffer, &handshake, length);

 socket->write_some(boost::asio::buffer(buffer, length));

 delete[] buffer;
 buffer = nullptr;

 ConsoleManager::WriteLine(" > sent test string");
}
Ну в общем, как я понимаю memcpy вообще как-то не правильно копирует структуру, хотя по результатам поиска вроде этот вариант выдают как правильный.

Последний раз редактировалось coNsept; 07.11.2015 в 20:26.
coNsept вне форума Ответить с цитированием
Старый 07.11.2015, 20:52   #7
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

Указатели по сети шлешь? Норм, чо.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 08.11.2015, 00:42   #8
coNsept
Форумчанин
 
Аватар для coNsept
 
Регистрация: 14.12.2009
Сообщений: 716
По умолчанию

Да, вы правы pproger, мне стыдно, оть так работает.

Код:
#pragma pack(push, 1)
 struct Handshake
 {
  int Length;
  wchar_t Text[];
 };
#pragma pack(pop)
coNsept вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
поиск unicode строки в html файле IvanKonst Общие вопросы Delphi 1 09.12.2013 14:33
Передача файлов по сокетам саша40 Работа с сетью в Delphi 43 01.12.2012 18:28
Передача файла по сокетам grorg Работа с сетью в Delphi 8 23.09.2012 19:41
[C][unicode] Преобразование регистра строки int Помощь студентам 1 15.02.2010 08:46
Передача файла по сокетам bigmak Помощь студентам 1 24.03.2009 12:50