Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/15: Рейтинг темы: голосов - 15, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 29.12.2011
Сообщений: 31

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

05.06.2012, 23:09. Показов 3263. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru