none
Сбивается кодировка в сокетах RRS feed

  • Вопрос

  • Всем доброго времени суток.

    Есть два приложения сервер и клиент. Пересылка сообщениями идет исправно, но пчему-то сообщения имеющие русские буквы отображаются как "???????"

    Вот код Сервера

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    using System.ComponentModel.DataAnnotations;
    using Server.Models;
    using Server.DataAccess;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace Server
    {
        class Program
        {
            static void Main(string[] args)
            {
                
                //старт сервера
                try
                {
                    StringBuilder input = new StringBuilder();
                    IPAddress ipAd = IPAddress.Parse("127.0.0.1");
                    TcpListener myList = new TcpListener(ipAd, 8001);
                    myList.Start();
                    Console.WriteLine("Сервер запущен на порту 8001...");
                    Console.WriteLine("Конечный ip-адрес и порт :" + myList.LocalEndpoint);
                    Console.WriteLine("Ожидание соединения.....");
    
                    Socket s = myList.AcceptSocket();
                    Console.WriteLine("Соединение успешно Установлено: " + s.RemoteEndPoint);
    
    
                    byte[] b = new byte[100];
                    int k = s.Receive(b);
                    Console.WriteLine("Команда получена...");
                    //формирование строки команды
                    for (int i = 0; i < k; i++)
                    {
                        input.Append(Convert.ToChar(b[i]));
                    }
    
    
                    //инициализация базы данных
                    Database.SetInitializer(new DbInitializator());
                    //объект базы данных
                    DictionaryDB _db = new DictionaryDB();
                    //слой данных
                    DataLayer dataLayer = new DataLayer();
                    string[] result = input.ToString().Split(' ');//newserv.CommandString.Split(' ');//str.Split(' ');
                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes(dataLayer.CommandPicker(result, _db)));
                    s.Close();
                    myList.Stop();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error..... " + e.StackTrace);
                }
            }
            
        }
    }
    

    Клиента

    class DictionaryClient
    {
    
    	public void connect(string ipaddress) {
    		
    		try {
                StringBuilder output = new StringBuilder();
    			TcpClient tcpclnt = new TcpClient();
    			Console.WriteLine("Подключение.....");
    			
    			tcpclnt.Connect(ipaddress,8001); // use the ipaddress as in the server program
    			
    			Console.WriteLine("Соединение прошло успешно");
    			Console.Write("Введите команду : ");
    			
    			String str=Console.ReadLine();
    			Stream stm = tcpclnt.GetStream();
    
                ASCIIEncoding asen = new ASCIIEncoding();
    			byte[] ba=asen.GetBytes(str);
    			Console.WriteLine("Передача.....");
    			stm.Write(ba,0,ba.Length);
    			
    			byte[] bb=new byte[100];
    			int k=stm.Read(bb,0,100);
    
    
                for (int i = 0; i < k; i++)
                {
                    output.Append(Convert.ToChar(bb[i]));
                }
                Console.WriteLine(output.ToString());
    			
    			tcpclnt.Close();
    		}
    		
    		catch (Exception e) {
    			Console.WriteLine("Error..... " + e.StackTrace);
    		}
    	}

    как решить проблему?

    21 августа 2012 г. 16:50

Ответы

  • А чего Вы хотели. На сервере Вы кодируете с использованием ASCIIEncoding, используются первые 128 символов юникода,

    string[] result = input.ToString().Split(' ');//newserv.CommandString.Split(' ');//str.Split(' ');
                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes(dataLayer.CommandPicker(result, _db)));

    а на клиенте уже декодируете как Unicode

    for (int i = 0; i < k; i++)
                {
                    output.Append(Convert.ToChar(bb[i]));
                }

    Char в C# представляет одиночный символ юникода. Отсюда и неверное отображение русских букв, так как они находятся высше в позиции.

    "как решить проблему?" - используйте UTF8Encoding, а так как у Вас сокеты, это почти не повлияет на производительность.


    • Помечено в качестве ответа Abolmasov Dmitry 23 августа 2012 г. 12:55
    21 августа 2012 г. 17:46
    Модератор
  • Используйте для кодирования и раскодирования одну и туже кодировку:

    byte[] b = Encoding.UTF8.GetBytes("Строка для конвертации");
    string result = Encoding.UTF8.GetString(b);

    • Помечено в качестве ответа Abolmasov Dmitry 23 августа 2012 г. 12:55
    22 августа 2012 г. 6:42
    Отвечающий

Все ответы

  • А чего Вы хотели. На сервере Вы кодируете с использованием ASCIIEncoding, используются первые 128 символов юникода,

    string[] result = input.ToString().Split(' ');//newserv.CommandString.Split(' ');//str.Split(' ');
                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes(dataLayer.CommandPicker(result, _db)));

    а на клиенте уже декодируете как Unicode

    for (int i = 0; i < k; i++)
                {
                    output.Append(Convert.ToChar(bb[i]));
                }

    Char в C# представляет одиночный символ юникода. Отсюда и неверное отображение русских букв, так как они находятся высше в позиции.

    "как решить проблему?" - используйте UTF8Encoding, а так как у Вас сокеты, это почти не повлияет на производительность.


    • Помечено в качестве ответа Abolmasov Dmitry 23 августа 2012 г. 12:55
    21 августа 2012 г. 17:46
    Модератор
  • менял кодировку, но видимо из-за чара ошибка остается.

    Не подскажите как исправить?

    22 августа 2012 г. 3:19
  • Используйте для кодирования и раскодирования одну и туже кодировку:

    byte[] b = Encoding.UTF8.GetBytes("Строка для конвертации");
    string result = Encoding.UTF8.GetString(b);

    • Помечено в качестве ответа Abolmasov Dmitry 23 августа 2012 г. 12:55
    22 августа 2012 г. 6:42
    Отвечающий