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

Передача объектов класса (TCP)

10.10.2017, 09:55. Показов 4090. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!
Пишу клиент-серверное приложение.
Основная задача сервера, обработка запросов и обращение к БД.

Возможность клиента - добавить/изменить/удалить данные в БД.

Т.е. серверная часть выступает в роли прослойки между клиентом и БД.

Идея была написать несколько классов, которые бы выступали в роли полей БД. (Пользователи, заявки).

Изначально порыскав по интернету, нашел некий шаблон для клиент-серверного приложения с помощью TcpClient.

Дальше был была написана dll с описание неких классов и возможностью серриализации и десериализации.
И возник вопрос, как распознавать типы объектов, а так же задачи для сервера (удалить/записать/добавить итд итп).
Решено было к сериализованому классу приклеивать несколько байт со служебной информации, где условно 0 байт тип команды/ 1 байт подтип команды / 2 байт тип объект.

Но в итоге, после добавления данных функций начало вываливаться исключение "двоичный поток 0 не содержит допустимого двоичного заголовка".

И тут я понял, что я ничего не понял =).
В общем мой недокод прилагаю.

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

clnt
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
namespace SocketClient
{
    class Clnt
    {
        public static bool Authorizat(Person person, NetworkStream stream)
        {
            bool flag = false;
    
            // преобразуем сообщение в массив байтов
            byte[] data = person.Serialization();
 
 
            data[0] = 0;
            data[1] = 0;
            // отправка сообщения
            if (stream.CanWrite)
                stream.Write(data, 0, data.Length);
            else Console.WriteLine("Занято");
            // получаем ответ
            data = new byte[1024]; // буфер для получаемых данных
            if (stream.CanRead)
                do
                {
                    Console.WriteLine("Получение потока");
                    stream.Read(data, 0, data.Length);
                }
                while (stream.DataAvailable);
            else Console.WriteLine("Не может быть считан");
            if (data[0] == 1)
            {
                Console.WriteLine("Удачно");
                flag = true;
            }
            else Console.WriteLine("Неудача");
            stream.Flush();
            return flag;
        }
        public static void AddRequest(Person person, NetworkStream stream)
        {
            Console.WriteLine("Введите запрос");
            string request = Console.ReadLine();
 
            Request req = new Request(person, request);
            byte[] data= req.Serialization();
            data[0] = 1;
            if (stream.CanWrite)
                stream.Write(data, 0, data.Length);
            else Console.WriteLine("Занято");
 
            stream.Flush();
 
        }
        const int port = 8888;
        const string address = "127.0.0.1";
        static void Main(string[] args)
        {
            //здесь будет вызов формы авторизации
            Console.Write("Введите свое имя:");
            string userName = Console.ReadLine();
 
            Person person=new Person (userName, userName, 000);
 
 
            TcpClient client = null;
            try
            {
                client = new TcpClient(address, port);
                NetworkStream stream = client.GetStream();
 
                while (true)
                {
                    //Авторизация
                   while (Authorizat(person, stream) == false)
                    {
                        //здесь будет вызов формы авторизации
                        Console.Write("Введите свое имя222:");
                      
                        person.FirstName = Console.ReadLine();
                    }
                    Console.WriteLine("WellDOne");
                  
                    AddRequest(person, stream);
                 
                
                 
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Main(args);
                // client.Close();
            }
        }
    }
}

srvr
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using System;
using SQLite;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using DataBase;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
//byte [0]=0 - авторизация
//byte [0]=1 - добавление request
namespace srvr
{
    class Srvr
    {
       static Database db=new Database("test.db");
       
        public static bool Authorizat(byte [] data, NetworkStream stream)
        {
            bool flag = false;
            DBCommand comand=new DBCommand();
            var person = comand.DeSerialization(data);
            
            var persons = db.ExecuteScalar<String>("SELECT * FROM Person WHERE FirstName = ?",person.FirstName);
            if (persons != null)
            {
                Console.WriteLine("ОТправка");
                // отправляем обратно, что аторизация успешна
                data = new byte[1];
                data[0] = 1;
                if (stream.CanWrite)
                    stream.Write(data, 0, data.Length);
                else Console.WriteLine("Занято");
                flag = true;
            }
            else
            {
                data = new byte[1];
                data[0] = 0;
                if (stream.CanWrite)
                {
                    Console.WriteLine("Отправка fail");
                    stream.Write(data, 0, data.Length);
                }
                else Console.WriteLine("Занято");
             
            }
            stream.Flush();
            return flag;
        }
        public static bool AddRequest(byte[] data, NetworkStream stream)
        {
            DBCommand command = new DBCommand();
            Console.WriteLine("Start Deser AddRequest");
            var request = command.DeSerialization(data);
            Console.WriteLine("Десер");
            db.Insert(request);
            db.ViewTable();
            stream.Flush();
            return true;
        }
 
        public class ClientObject
        {
            public TcpClient client;
            public ClientObject(TcpClient tcpClient)
            {
                client = tcpClient;
            }
 
            public void Process()
            {
                NetworkStream stream = null;
                try
                {
                    stream = client.GetStream();
                    byte[] data = new byte[1024]; // буфер для получаемых данных
                    for(int i=0;i>-1;i++)
                    {
                        // получаем сообщение
                        StringBuilder builder = new StringBuilder();
                        int bytes = 0;
                        if (stream.CanRead)
                            do
                            {
                                Console.WriteLine("Получение потока");
                                stream.Read(data, 0, data.Length);
                            }
                            while (stream.DataAvailable);
                        else Console.WriteLine("Не может быть считан");
                       
                        while (stream.DataAvailable);
     
                        switch (data[0])
                        {
                            case 0:
                                {
                                    Authorizat(data, stream);
                                    break;
                                }
                            case 1:
                                {
                                    AddRequest(data, stream);
                                    break;
                                }
 
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
 
                    if (stream != null)
                    {
                        Console.WriteLine("stream != null");
                        stream.Close();
                    }
                    if (client != null)
                    {
                  //      client.Close();
                        Console.WriteLine("client != null");
                    }
                }
            }
        }
 
        const int port = 8888;
        static TcpListener listener;
        static void Main(string[] args)
        {
            db.Execute("DROP TABLE Person");
            Person person = new Person("asd", "asd", 123);
            db.CreateTable<Person>();
            db.Insert(person);
            db.ViewTable();
 
      
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
                listener.Start();
                Console.WriteLine("Ожидание подключений...");
 
                while (true)
                {
                    TcpClient client = listener.AcceptTcpClient();
                    ClientObject clientObject = new ClientObject(client);
 
                    // создаем новый поток для обслуживания нового клиента
                    Thread clientThread = new Thread(new ThreadStart(clientObject.Process));
                    clientThread.Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (listener != null)
                    listener.Stop();
            }
        }
    
    }
}
dll класса
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.Linq;
using SQLite.Net;
using SQLite.Net.Attributes;
using SQLite.Net.Interop;
using SQLite.Net.Platform.Win32;
using Path = System.IO.Path;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using SQLite;
using System.Globalization;
namespace DataBase
{
    //0 байт тип команды/ 1 байт подтип команды / 2 байт тип объект
 
 
    [Serializable]
    public class DBCommand 
    {
        public DBCommand(string firstName, string lastName, int phoneNumber) { }
        public DBCommand(Person per, string str) { }
        public DBCommand() { }
 
        // Десериализация 
        public dynamic DeSerialization (byte[] bytes)
        {      
            MemoryStream stream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            stream.Write(bytes, 0, bytes.Length);
            stream.Seek(3, SeekOrigin.Begin);
            //определение типа принятого объекта // 0 - person,  1- Request 
           
            Console.Write("{0} ", stream);
            if (bytes[2] == 0)
            {
                Console.WriteLine("Deser Person");
                return (Person)formatter.Deserialize(stream);
            }
            else if (bytes[2] == 1)
            {
                Console.WriteLine("Deser request");
                return (Request)formatter.Deserialize(stream);
            }
            else
            { Console.WriteLine("Deser NULL"); return null; }
        }
 
        //Сериализация объекта для передачи
        public byte[] Serialization()
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, this);
            byte[] tmp = stream.ToArray();
            //добавление флага для определения типа переданного объекта
            byte[] msg = new byte[tmp.Length + 3];
            msg[0] = 9;
            msg[1] = 9;
            if (this is Person)
                msg[2] = 0;
            else if (this is Request)
                msg[2] = 1;
 
            for (int i = 3; i <= tmp.Length; i++)
                msg[i] = tmp[i - 3];
            for (int i = 0; i < msg.Length; i++)
                Console.Write("{0} ", msg[i]);
            return msg;
        }
 
 
        //создание полей
 
 
        //Добавление полей в базуданных
        public void AddRequestToDB (Database db, Request req)
        {
            if (req!=null)
            db.Insert(req);
        }
        public void AddPersonToDB(Database db, Person per)
        {
            if (per != null)
                db.Insert(per);
        }
        //вывод в консоле 
 
 
 
 
 
    }
 
 
 
    [Serializable]
    public class Person :DBCommand
    {
 
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int PhoneNumber { get; set; }
 
        public override string ToString()
        {
            return string.Format("{0:} | {1:} | {2:} | {3:}", Id, FirstName, LastName, PhoneNumber);
        }
 
 
        public Person() { }
 
        public Person( string firstName, string lastName, int phoneNumber) : base (firstName, lastName, phoneNumber)
        {
            FirstName = firstName;
            LastName = LastName;
            PhoneNumber = phoneNumber;
        }
        
    }
 
    [Serializable]
    public class Request :DBCommand
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        [Indexed]
        public int PersonId { get; set; }
 
        public DateTime Time { get; set; }
        public string Req { get; set; }
 
        public override string ToString()
        {
            return string.Format("{0:} {1:MMM dd yy}    {2:}", Id, Time, Req);
        }
 
 
        public Request() { }
        public Request( Person per, string req) : base (per, req)
        {
            Time = DateTime.Today;
            PersonId = per.Id;
            Req = req;
        }
 
    }
 
    public class Database : SQLiteConnection
    {
        public Database(string path) : base(new SQLitePlatformWin32(), path)
        {
            CreateTable<Person>();
            CreateTable<Request>();
        }
 
        public void ViewTable()
        {
            Console.WriteLine("Person_______");
            foreach (var il in this.Table<Person>())
            {
                Console.WriteLine(il);
            }
            Console.WriteLine("Request_______");
            foreach (var il in this.Table<Request>())
            {
                Console.WriteLine(il);
            }
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.10.2017, 09:55
Ответы с готовыми решениями:

Передача ссылки на объект класса (массив объектов класса)
Доброго времени, уважаемые форумчане. Прошу прощения за столь глупый вопрос, но правда очень долго туплю и не могу понять как это...

Сериализация объекта класса и передача его по TCP
Отредактировал найденный пример из сети, но при работе клиента выбивает ошибку: Необработанное исключение типа ссылая на...

Передача объектов другого класса в конструктор через params
Здравствуйте. В учебнике есть пример: класс Figure, класс Point. В зависимости от того, сколько &quot;вершин&quot; принимает конструктор...

2
0 / 0 / 0
Регистрация: 10.10.2017
Сообщений: 3
10.10.2017, 12:36  [ТС]
Или проще сделать это через json?

Появилась тут идея прикрутить еще один класс DataTravel, который будет содержать в себе некий флаг и объекты других классов.

При получении обрабатывать данный флаг и по нему уже ориентироваться, к какому из вложенных классов обратиться или какой действие необходимо сделать.
0
[Bicycle Reinventor]
 Аватар для Exerion
332 / 270 / 109
Регистрация: 19.10.2011
Сообщений: 668
Записей в блоге: 2
10.10.2017, 14:14
Почитайте про WCF и EntityFramework.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.10.2017, 14:14
Помогаю со студенческими работами здесь

Массив объектов базового класса, позволяющий работать с набором объектов — чтение, вывод
Расширить программы с классами. Каждый разработанный класс считать базовым; для каждого такого класса описать производный класс - массив...

Создание объекта класса, который будет содержать указанное количество объектов другого класса
Здравствуйте. Я сейчас только учусь, помогите, пожалуйста. Задача такая: необходимо создать класс кораблика из игры &quot;Морской...

Поле класса содержит массив объектов другого класса
Добрый день. Есть класс Queue,который как поле содержит массив объектов на класс Pers. public class Queue { private...

Коллекция объектов одного класса в экземпляре другого класса
Извиняюсь, если написал не совсем адекватный заголовок. В общем, у меня есть такая модель: public class AssetsFlowsViewModel { ...

TCP передача файлов
Здравствуйте, разбирался в структуре и способе работы с протоколом по передачи данных TCP, сделал сервер на С++ (Linux) так же есть клиент...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru