отправка строки Unicode через winsock в c ++ - PullRequest
2 голосов
/ 08 ноября 2011

Я изменил приведенный ниже код для отправки строки Unicode клиенту.

пожалуйста, проверьте его и скажите мне, почему в клиенте я не могу получить какие-либо данные, когда txt содержит символ Unicode ??

bool write_to_descriptor( int desc, wchar_t *txt, int length )
//bool write_to_descriptor( int desc, char *txt, int length )
{
    int iStart;
    int nWrite;
    int nBlock;

    if ( length <= 0 )
    length = strlen(txt);

    for ( iStart = 0; iStart < length; iStart += nWrite )
    {
    nBlock = UMIN( length - iStart, 4096 );
    if ( ( nWrite = send( desc, txt + iStart, nBlock, 0 ) ) < 0 )
        { perror( "Write_to_descriptor" ); return FALSE; }
    }

    return TRUE;
}

1 Ответ

4 голосов
/ 08 ноября 2011

Для протокола TCP (и UDP) такой вещи, как wchar_t, не существует. А для функции send не существует такой вещи, как wchar_t. Есть только необработанные двоичные данные - последовательность байтов.

Проблемы этого кода следующие:

  1. length = strlen(txt); - Функция, которая вычисляет длину строки с нулевым символом в конце, равна wcslen. Для строки UTF16 с прямым порядком байтов (это широкая строка на платформе WIN32), если первый широкий символ является символом ASCII (или Latin1), тогда strlen возвращает 1 (поскольку второй байт является старшим байтом первого широкого символа и содержит ноль для символа ASCII).

  2. nWrite = send( desc, txt + iStart, nBlock, 0 ) Вы send БАЙТОВ не символов (и особенно не широких символов ). Поэтому, если вы хотите отправить двоичное представление широкой строки (которое не является переносимым и, следовательно, не должно передаваться по сети, но будет работать, если клиент и сервер находятся на одной платформе), вы должны сделать это следующим образом: nWrite = send( desc, txt + iStart, sizeof(wchar_t)*nBlock, 0 ). Когда вы отправляете это как вы, вы отправляете только половину своей широкой строки. Конечно, приложение на другом конце соединения должно знать, что отправлено двоичное представление широкой строки для конкретной платформы (не строка ASCII или что-то в этом роде).

  3. Конечно, вы никогда не должны делать что-то вроде отправки специфичного для платформы / компилятора внутреннего двоичного строкового представления. Вам следует использовать некоторый хорошо документированный сетевой протокол (например, telnet, HTTP или любой другой), большинство из которых используют кодировку символов ASCII или UTF-8 для представления текста. Поэтому вам следует преобразовать ваши широкие строки в представление, требуемое протоколом по вашему выбору.

...