Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сокеты и передача объеков свобственного класса 
V
    Опции темы
albert21
  Дата 9.5.2006, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 10.1.2006

Репутация: нет
Всего: нет



Всем доброго дня.
Вот решил разобраться с работой с сокетами в шарпе! Текст передаётся, получается, а как передать объект собственного класса? Как реализовать перевод объекта своего класса в массив байтов? 
--------------------
http://www.certifications.ru/publicresults.php?tu_id=45939
PM MAIL   Вверх
mr.DUDA
Дата 10.5.2006, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 2
Всего: 232



Через сериализацию. Самое простое - это пометить свой класс атрибутом [Serializable] и вызвав BinaryFormatter.Serialize сохранить объект в stream. Аналогично (Deserialize) объект восстанавливается из сериализованного представления. Если работаем с массивом байт, то как промежуточный stream прокатит MemoryStream. 


--------------------
user posted image
PM MAIL WWW   Вверх
albert21
Дата 10.5.2006, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 10.1.2006

Репутация: нет
Всего: нет



Проблема, mr.DUDA, помогите пожалуйста
Вот, попробовал! Ошибается

Класс рукописный
Код

    [Serializable]
    class MyInt
    {
        private int a;
        public MyInt(int b)
        {
            a = b;
        }
        public void Inc()
        {
            a = a + 1;
        }
        public string GetStr()
        {
            return a.ToString();
        }
    }


Клиент
Код

    class Program
    {
        static void Connect(String server, MyInt proba)
        {
            try
            {
                Int32 port = 13000;
                TcpClient client = new TcpClient(server, port);

                NetworkStream stream = client.GetStream();
                BinaryFormatter frmt = new BinaryFormatter();
                frmt.Serialize(stream, proba);

                Console.WriteLine("Sent: {0}");

                stream.Close();
                client.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }

            Console.WriteLine("\n Press Enter to continue...");
            Console.Read();
        }

        static void Main(string[] args)
        {
            string host;


            if (args.Length == 0)
                host = Dns.GetHostName();
            else
                host = args[0];

            MyInt proba = new MyInt(2);
            Connect(host, proba);
        }
    }


Сервер
Код

    public void StartObject()
    {
        TcpListener server = null;
        try
        {
            // Set the TcpListener on port 13000.
            Int32 port = 13000;
            IPAddress localAddr = IPAddress.Parse("127.0.0.1");

            // TcpListener server = new TcpListener(port);
            server = new TcpListener(localAddr, port);

            // Start listening for client requests.
            server.Start();

            // Enter the listening loop.
            while (true)
            {
                Console.Write("Waiting for a connection... ");
                TcpClient client = server.AcceptTcpClient();
                Console.WriteLine("Connected!");
                NetworkStream stream = client.GetStream();
                BinaryFormatter bn = new BinaryFormatter();
                MyInt m = (MyInt)bn.Deserialize(stream);
                Console.WriteLine(m.GetStr());

                // Shutdown and end connection
                client.Close();
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }
        finally
        {
            // Stop listening for new clients.
            server.Stop();
        }
        Console.WriteLine("\nHit enter to continue...");
        Console.Read();
    }

    public static void Main()
    {
        StartObject();
    }


Подскажите пожалуйста в чём ошибка? Или может есть свой пример

Добавлено @ 16:02 
Ошибка происходит во время приёма сообщения сервером 
--------------------
http://www.certifications.ru/publicresults.php?tu_id=45939
PM MAIL   Вверх
mr.DUDA
Дата 10.5.2006, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 2
Всего: 232



Судя по всему это из-за того, что сервер пытается десериализовать объект у которого прописано имя assembly, отсутствующей на сервере. То есть, класс MyInt на сервере - это один класс, а присланный клиентом в потоке объект - это уже другой класс, т.к. имя assembly там другое. Посему, нужно либо запихнуть сериализуемый класс в отдельную сборку, которая есть и у сервера и у клиента, либо пользоваться XML- либо SOAP-сериализацией.  


--------------------
user posted image
PM MAIL WWW   Вверх
albert21
Дата 10.5.2006, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 10.1.2006

Репутация: нет
Всего: нет



Я попробую! Но я обнаружил, что де сериализация MyInt не проходит даже в рамках одного класса:
Код

            BinaryFormatter frmt = new BinaryFormatter();
            MemoryStream mstr = new MemoryStream();
            frmt.Serialize(mstr, proba);
            MyInt v=(MyInt)frmt.Deserialize(mstr);
            Console.WriteLine(v.GetStr());


Может это из-за того, что не указано свойство Capacity потока MemoryStream?
Пробовал применить 
Код

int i=sizeof(MyInt);

Не компилится!!! Как исправить? 
--------------------
http://www.certifications.ru/publicresults.php?tu_id=45939
PM MAIL   Вверх
albert21
Дата 10.5.2006, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 10.1.2006

Репутация: нет
Всего: нет



Цитата

Судя по всему это из-за того, что сервер пытается десериализовать объект у которого прописано имя assembly, отсутствующей на сервере. То есть, класс MyInt на сервере - это один класс, а присланный клиентом в потоке объект - это уже другой класс, т.к. имя assembly там другое. Посему, нужно либо запихнуть сериализуемый класс в отдельную сборку, которая есть и у сервера и у клиента, либо пользоваться XML- либо SOAP-сериализацией.  


Всё верно, mr.DUDA! Спасибо! Нужен комментарий на предыдущий пост smile 
--------------------
http://www.certifications.ru/publicresults.php?tu_id=45939
PM MAIL   Вверх
mr.DUDA
Дата 11.5.2006, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 2
Всего: 232



Цитата(albert21 @  10.5.2006,  21:41 Найти цитируемый пост)
Нужен комментарий на предыдущий пост   

Всё дело в том, что сериализация идёт в поток (MemoryStream), поток имеет такое свойство как текущая позиция, и после сериализации позиция установлена в конце потока. Десериализация не пройдёт, если не передвинуть позицию с пом. Seek(0, SeekOrigin.Begin) на начало потока. 


--------------------
user posted image
PM MAIL WWW   Вверх
albert21
Дата 11.5.2006, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 10.1.2006

Репутация: нет
Всего: нет



Спасибо, mr.DUDA! 
--------------------
http://www.certifications.ru/publicresults.php?tu_id=45939
PM MAIL   Вверх
mr.DUDA
Дата 11.5.2006, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 2
Всего: 232



пожалуйста! 


--------------------
user posted image
PM MAIL WWW   Вверх
CityAC
Дата 19.9.2007, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 161
Регистрация: 3.11.2006
Где: Украина Горловка

Репутация: нет
Всего: 1



Чтоб не плодить похожие темы пишу здесь. Вопрос сходный:
На сервере есть экземпляр класса DataRow как его сериализовать для передачи на клиент?
Я так понимаю если свой класс то можно поставить метку [Serializable] а как тут быть?
И сюда загляните Pls. Нужны советы.

Это сообщение отредактировал(а) CityAC - 19.9.2007, 23:55
--------------------
Вижу цель, не вижу припятствий.  
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Распределённые приложения и сеть | Следующая тема »


 




[ Время генерации скрипта: 0.0653 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.