0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31

TCP чат: обрезаются слова, напечатанные кириллицей

05.06.2012, 23:09. Показов 3273. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здраствуйте. У меня есть соурс tcp чата, он написан не мной, но работает так как мне нужно. Но есть небольшая проблема - при написании русских символов в чат, он их обрабатывает так:
"абв" - выведет "а".
"йцукенгшщзхъ" - выведет "йцукен".

Даже не знаю куда рыть, ведь он "половину" символов распознает, а вторую съедает

Соурс в приложении
Вложения
Тип файла: zip tcpchat.zip (28.7 Кб, 62 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.06.2012, 23:09
Ответы с готовыми решениями:

Чат на tcp/ip
Хочу написать чат на tcp/ip. Но не могу додуматься как реализовать чисто логически кое-какие действия. Получается так: Допустим есть...

TCP чат
добрый день, решил написать онлайн чат. все вроде бы сделал, но в ходе работы вылазиют непонятные ошибки, кто может помочь (ошибка в 141...

TCP-Чат
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using...

8
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
05.06.2012, 23:17
Хм, кодировка UTF8. Вероятнее всего в местах, где создается буфер, он создается вдвое меньшей длины, чем нужно. Скорее всего это из-за того, что исходный код был написан для кодировки ASCII, где один символ представляется в виде одного байта, а кто-то сел и заменил кодировку с ASCII на UTF8 (один символ - два байта), но размер выделяемого буфера не исправил.
1
0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31
05.06.2012, 23:55  [ТС]
Мне достаточно изменить
Encoding.UTF8.GetBytes(strMessage)
на
Encoding.ASCII.GetBytes(strMessage)
?

Добавлено через 2 минуты
Нет, недостаточно
Появились вопросики, но зато для каждого русского символа, а не один из трех.
Можете посоветовать следущий ход?
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
06.06.2012, 00:19
Цитата Сообщение от LongMan Посмотреть сообщение
Появились вопросики, но зато для каждого русского символа
Та не в вопросиках дело (кстати свидетельствует о том, что указана неверно кодировка) и не в их количестве, а в количестве занимаемого места.
В ASCII нет русских символов, там только первые 128 символов: десяток вспомогательных, цифры и английские буквы. Я же говорю: увеличить размер буфера надо, вот только где - тяжело сказать, так как то ли клиент не все отправляет, то ли сервер не все обрабатывает, то ли оба случая сразу.
Ход такой: с помощью дебагера измерить размер отправляемого и получаемого сообщения в байтах, чтобы узнать, кто виноват.
К примеру, для строки "йцукенгшщзхъ", состоящей из 12 символов, должно получится 24 байта, а не 12.
1
0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31
06.06.2012, 10:23  [ТС]
C#
1
messageTxt.Lenght * sizeof(char);
Показал что везде 24 байта.

Ну есть такой код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
byte [] byteData = msgToSend.ToByte();
ClientInfo clientInfo = new ClientInfo();
clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None,
                                new AsyncCallback(OnSend), clientSocket); 
 
        public byte[] ToByte()
        {
            List<byte> result = new List<byte>();
 
            //First four are for the Command
            result.AddRange(BitConverter.GetBytes((int)cmdCommand));
 
            //Add the length of the name
            if (strName != null)
                result.AddRange(BitConverter.GetBytes(strName.Length));
            else
                result.AddRange(BitConverter.GetBytes(0));
 
            //Length of the message
            if (strMessage != null)
                result.AddRange(BitConverter.GetBytes(strMessage.Length));
            else
                result.AddRange(BitConverter.GetBytes(0));
 
            //Add the name
            if (strName != null)
                result.AddRange(Encoding.UTF8.GetBytes(strName));
 
            //And, lastly we add the message text to our array of bytes
            if (strMessage != null)
                result.AddRange(Encoding.UTF8.GetBytes(strMessage));
 
            return result.ToArray();
        }
Еще есть везде такое:

C#
1
byteData = new byte[1024];
Пробовал 2048, 4096...

Добавлено через 13 минут
Ну вот результаты еще, только не sizeof, а
C#
1
MessageBox.Show("[SERVER] TXT: " + strMessage + " BYTES:" + Encoding.UTF8.GetByteCount(strMessage).ToString());
А есть еще вот что:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        public Data(byte[] data)
        {
            //The first four bytes are for the Command
            this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);
 
            //The next four store the length of the name
            int nameLen = BitConverter.ToInt32(data, 4);
 
            //The next four store the length of the message
            int msgLen = BitConverter.ToInt32(data, 8);
 
            //This check makes sure that strName has been passed in the array of bytes
            if (nameLen > 0)
                this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
            else
                this.strName = null;
 
            //This checks for a null message field
            if (msgLen > 0)
                this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
            else
                this.strMessage = null;
        }
Миниатюры
TCP чат: обрезаются слова, напечатанные кириллицей   TCP чат: обрезаются слова, напечатанные кириллицей   TCP чат: обрезаются слова, напечатанные кириллицей  

0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
06.06.2012, 11:33
Хм, а вы пробовали на сервер отправлять больше одного слова? К примеру, "Тестовое сообщение"?
На клиенте показало "стТестово", а на сервере "ст?". Или именовать клиента русскими буквами - приходит кривая половина.
В общем, на сервере метод Data(byte[] data) и на клиенте метод ToByte() следует полностью переписать!
Это же что там за фигня использовалась? BitConverter.GetBytes? Кто вас такому бреду научил?
По-поводу того, как я узнал: я же говорил - буфер создается половинного размера!!!
Зайдите в метод Data и в местах инициализации переменные nameLen и msgLen удвойте! На сервер придет полное имя и сообщение, только слегка поврежденное из-за ваших непонятных магических чисел 4, 8 и 12.

Цитата Сообщение от LongMan Посмотреть сообщение
messageTxt.Lenght * sizeof(char);
Так мерять размер строки не есть верно!!! Ровно как и через BitConverter.GetBytes!!!
И какого черта приложение висит в диспетчере задач, если оно завершилось?
Вот в общем пища для ума:
C#
1
2
3
4
5
6
7
8
private static void Main()
{
    string message = "Тестовое сообщение";
    byte[] data = Encoding.UTF8.GetBytes(message); // Преобразовываю строку в массив байтов
    string result = Encoding.UTF8.GetString(data); // Преобразовываю массив байтов в строку
    Console.WriteLine(data.Length); // Длина строки в байтах
    Console.WriteLine(result); // Преобразованная строка
}
1
0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31
06.06.2012, 11:47  [ТС]
Прошу не ругать меня - код не мой, я лишь хотел адаптировать его для своей локали.
Попробую сначала удвоить "эти" числа.
0
Злой няш
 Аватар для I2um1
2136 / 1505 / 565
Регистрация: 05.04.2010
Сообщений: 2,881
06.06.2012, 11:53
LongMan, удвоение решает проблему лишь частично, так как там строку вырезали по частям с некоторым смещением, из-за чего будут поврежденные данные. Проще было преобразовывать полностью все сообщение туда и обратно и работать уже со строкой. К примеру придумать такой синтаксис:
<команда>-<имя пользователя>:<сообщение>
И с помощью Split или регулярного выражения вырезать нужное из строки.
1
0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31
06.06.2012, 12:26  [ТС]
Да, вы правы, удовение изменило "начало" считывания байтов.
Попробую изменить способ отправки байтов на свой. О результатах сообщу.

Добавлено через 28 минут
Решил проблему, спасибо вам большое.

Длина сообщения была неверной:
C#
1
result.AddRange(BitConverter.GetBytes(strMessage.Length));
Изменил:
C#
1
result.AddRange(BitConverter.GetBytes(Encoding.UTF8.GetByteCount(strMessage)));
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.06.2012, 12:26
Помогаю со студенческими работами здесь

TCP чат-сервер
Здравствуйте! Нужна помощь с таким заданием: На базе шаблона параллельного эхо-сервера, использующего модель “один клиент - один поток”,...

Многопользовательский TCP чат
Для отправки сообщений юзаю PrintWriter, поэтому flush'ить не надо. Вижу на сервере что юзеры подсоединяются, но сообщения не...

Чат на сокетах (TCP)
как реализовать? в принципе работал с сокетами, но не понимаю как конкретно чат делается? ведь всегда должен быть сервер по идее, я могу...

Чат на протоколе TCP
Доброго времени суток Пишу чат на протоколе TCP и столкнулся с такой проблемой: дублируется сообщение себе же... то есть я пишу, как...

TCP чат на 2 и более пользователей
Нужно сделать чат на двух и более пользователей. Сервер принимает данные только от одного пользователя. Как сделать сервер многопоточный?...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru