Как отправить широкие символы с помощью функции send () winsock? - PullRequest
2 голосов
/ 04 декабря 2010

Здесь указано , что функция send ожидает const char *.

Как отправить широкие символы?Я попробовал следующее:

void MyClass::socksend(const wchar_t* wbuffer) {
   int i;
   char *buffer = (char *)malloc( MB_CUR_MAX );
   wctomb_s(&i,buffer, MB_CUR_MAX, (wchar_t)wbuffer);
   int buflen = strlen(buffer) + 2;
   char sendbuf[DEFAULT_BUFLEN];
   strcpy_s(sendbuf,buflen,buffer);
   sendbuf[buflen - 1] = '\n';
   int senderror = send(this->m_socket, sendbuf, buflen, 0);
   // error handling, etc goes here...

}

Это не делает то, что я ожидаю.Кажется, он ничего не посылает в сокет.Как мне это исправить?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2010

Что такое широкий символ в первую очередь?Это целые значения шире, чем 8-битные;это означает, что вам придется обращаться с Endianness.Вам необходимо закодировать ваш массив широких символов в массив символов, а затем отправить его как массив символов.На принимающей стороне необходимо декодировать массив символов в массив широких символов.

Функция wctomb_s кодирует только один широкий символ до массив символов .Функция, которую вы хотите закодировать массив широких символов до массив символов - это wcstombs_s.Соответственно, для декодирования используйте mbstowcs_s.

с пропущенной обработкой ошибок (не проверено):

void MyClass::socksend(const wchar_t* wbuffer) { 
   // determine the required buffer size
   size_t buffer_size;
   wcstombs_s(&buffer_size, NULL, 0, wbuffer, _TRUNCATE);

   // do the actual conversion
   char *buffer = (char*) malloc(buffer_size);
   wcstombs_s(&buffer_size, buffer, buffer_size, wbuffer, _TRUNCATE);

   // send the data
   size_t buffer_sent = 0;
   while (buffer_sent < buffer_size) {
       int sent_size = send(this->m_socket, buffer+buffer_sent, buffer_size-buffer_sent, 0);
       buffer_sent += sent_size;
   }

   // cleanup
   free(buffer);
}
0 голосов
/ 04 декабря 2010

Обратите внимание, что я не уверен в правильном способе передачи широких строк символов через сокет, так что для этой части вы по своему усмотрению. Я знаю, что он был описан как довольно волосатый и запутанный. :) Учитывая это, если другая сторона сокета ожидает строку wchar_t, вы можете использовать wcslen, чтобы получить длину строки, на которую указывает wbuffer, что дает вам

int senderror = send( this->m_socket, (char *)wbuffer, wcslen( wbuffer ) * sizeof( wchar_t ), 0 );

Есть также несколько возможных ошибок в вашем коде. Если вам нужно преобразовать строку wchar_t в многобайтовую, вы должны использовать wcstombs_s вместо wctomb_s. wctombs_s преобразует один символ за раз, в то время как wcstombs_s преобразует строку.

Если результирующая строка длиннее DEFAULT_BUFLEN, вы в конечном итоге искалечите строку с помощью \ n и отбросите все данные, длина которых превышает DEFAULT_BUFLEN.

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

См. здесь для получения дополнительной информации.

...