Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2011, 00:01   #1
JeyKip
Форумчанин
 
Регистрация: 18.09.2009
Сообщений: 133
Вопрос Базы данных. Клиент-серверное приложение.

Всем доброго времени суток! Была написана простенькая программа, позволяющая работать с базой данных (всего одна таблица). Теперь ее нужно разделить на сервер (содержит только БД) и клиента, который смог бы работать с БД на сервере. Думал для этого передавать клиенту с сервера DataSet, но не смог найти как, и целесообразно ли это вообще. Подскажите пожалуйста, как можно это реализовать. Либо любой другой подход. И какой вообще принцип обмена данными между между клиентом и сервером при работе с БД? Заранее премного благодарен за любую оказанную помощь.

P.S. Если нет соображений или неохота ими поделиться, просьба не писать сообщения рода "Google в помощь" и т.п. По крайне мере мне не удалось там найти ответ на мой вопрос, иначе этого топика не было бы.
JeyKip вне форума Ответить с цитированием
Старый 12.04.2011, 08:00   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Чего за СУБД то использовалась? Если Access, то тупо кидайте файл на сервер, расшаривайте его и подключайтесь к нему из программы. Если более серьезная СУБД, то настраиваете её на сервере, ставите там свою базу, а в программе в ConnectionString меняете путь до базы с указанием этого самого сервера.
pu4koff вне форума Ответить с цитированием
Старый 12.04.2011, 12:56   #3
JeyKip
Форумчанин
 
Регистрация: 18.09.2009
Сообщений: 133
По умолчанию

Дабы топик не был бесполезным, хочу привести пример пересылки DataSet с сервера клиенту и отображение его в клиентском DataGridView.
Необходимый код для сервера
Код:
      
                //ставим прослушку по умолчанию на 200 порт   
                int port = 200;
                //устанавливаем IP-адресс сервера с БД
                IPAddress ip_adress = IPAddress.Parse("127.0.0.1");
                //создали TcpListener
                server = new TcpListener(ip_adress, port);
                //запустили прослушивание на подключения клиентов
                server.Start();
далее запущен бесконечный цикл на ожидание запросов на подключение от клиентов

Код:
        
        while (true)
                {   
                    //поймали клиента TcpClient                
                    client = server.AcceptTcpClient();
                    //получили поток клиента
                    NetworkStream client_streem = client.GetStream();
                    //послали переконвертированный DataSet на по этому потоку
                    client_streem.Write(GetByteDataSet(oscar_dataset), 0, GetByteDataSet(oscar_dataset).Length);
                    //выдали сообщение о подключении
                    MessageBox.Show("Подключено");
                }
а теперь, собственно, сама функция GetByteDataSet
Код:
        //обязательно нужно конвертить в byte[], т.к. этот тип используется для обмена 
        //сообщениями между клиентом и сервером
        private byte[] GetByteDataSet(DataSet data)
        {
            //создали буфер для переконвертированного DataSet
            byte[] data_rez = null;
            //создали поток, используемый для сериализации в качестве временного буфера
            MemoryStream mem_streem = new MemoryStream();
            //объект, выполняющий сериализацию
            BinaryFormatter bin_format = new BinaryFormatter();

            //собственно сама сериализация из DataSet в MemoryStreem
            bin_format.Serialize(mem_streem, data);
            //перевели в массив byte[]
            data_rez = mem_streem.ToArray();

            //обрубили поток
            mem_streem.Close();
            mem_streem.Dispose();

            return data_rez;
        }
а теперь код для клиента, который принимает byte[] и конвертит в DataSet

Код:
        //обработчик кнопки для подключения к серверу
        private void connect_to_server_Click(object sender, EventArgs e)
        {
            //создаем клиента на подключение к 200 порту по IP-сервера
            TcpClient client = new TcpClient("127.0.0.1", 200);
            //получаем поток для этого клиента. По нему пошел DataSet
            NetworkStream client_streem = client.GetStream();
            //опять врменный буфер
            MemoryStream streem = new MemoryStream();
            //и для сериализации
            BinaryFormatter bf = new BinaryFormatter();

            //создаем объект DataSet и производим для него десериализацию клиентского потока
            DataSet data = (DataSet)bf.Deserialize(client_streem);
            //отобразили таблицу с индексом 0 в клиентском DataGridView
            //а т.к. таблица у меня всего одна, то и выбор, соответственно, невелик
            dataGridView1.DataSource = data.Tables[0].DefaultView;            
        }
для того, чтобы все это работало, необходимы следующие пространства имен:
Код:
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
вот, собственно говоря, и все...по мере написания лабы выкину еще че-нибудь...

Последний раз редактировалось JeyKip; 12.04.2011 в 14:28.
JeyKip вне форума Ответить с цитированием
Старый 12.04.2011, 14:40   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Какой ужас... Зачем такой изврат? Такие задания уже в ВУЗах дают, чтобы студенты смолоду писали всякий ужас?
pu4koff вне форума Ответить с цитированием
Старый 12.04.2011, 16:29   #5
JeyKip
Форумчанин
 
Регистрация: 18.09.2009
Сообщений: 133
По умолчанию

дали только задание, а кто и как будет реализовывать - дело абсолютно каждого... а что не так, может подскажешь..? Буду благодарен.! И вот еще. В бесконечном цикле идет проверка на подключение клиентов. На строчке
Код:
 client = server.AcceptTcpClient();
до нового подключения останавливается и, следовательно, никакие запросы от клиентов не обраюатываются. Как сделать так, чтобы сервер всегда адекватно реагировал на новое подключение и в то же время мог нормально работать с запросами от других клиентов?

Последний раз редактировалось JeyKip; 12.04.2011 в 16:38.
JeyKip вне форума Ответить с цитированием
Старый 13.04.2011, 08:27   #6
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Цитата:
Сообщение от JeyKip Посмотреть сообщение
дали только задание, а кто и как будет реализовывать - дело абсолютно каждого... а что не так, может подскажешь..? Буду благодарен.!
Ну, например, так не делают. Это как правой рукой левое ухо чесать, даже еще хуже. Задание звучит как написать трёхзвенку? Сомневаюсь. Если же нужно просто клиент-серверное приложение, то я в первом своём посте написал как это делается. Не нужна никакая программа сервер. Сервером будет являться СУБД.
Цитата:
Сообщение от JeyKip Посмотреть сообщение
И вот еще. В бесконечном цикле идет проверка на подключение клиентов. На строчке
Код:
 client = server.AcceptTcpClient();
до нового подключения останавливается и, следовательно, никакие запросы от клиентов не обраюатываются. Как сделать так, чтобы сервер всегда адекватно реагировал на новое подключение и в то же время мог нормально работать с запросами от других клиентов?
Как вариант: в главном потоке слушаем только новых клиентов, а когда клиент пришел - выделяем под него отдельный поток и в этом потоке работаем уже только с ним. В итоге получаем по отдельному потоку на клиента.
pu4koff вне форума Ответить с цитированием
Старый 13.04.2011, 23:29   #7
JeyKip
Форумчанин
 
Регистрация: 18.09.2009
Сообщений: 133
По умолчанию

Задание стоит следующим образом: "Разработать клиент-серверное приложение для работы с БД. Сервер должен подключаться к файлу БД, а клиент должен при подключении к серверу получать эти данные на обработку." Обработка данных происходит на клиенте, а при сохранении должны отправляться серверу, а он, в свою очередь, должен скидывать сохранение в файл БД.

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

Код:
while (true)
                {
                    //если кто-то просится в гости
                    if (server.Pending())
                    {
                        //определяем его как клиента. Всем рады
                        client = server.AcceptTcpClient();
                        //а теперь поток для общения
                        client_streem = client.GetStream();
                        //и сразу кинуть в клиента DataSet'ом переконвертенным
                        client_streem.Write(GetByteDataSet(oscar_dataset), 0, GetByteDataSet(oscar_dataset).Length);
                        Console.WriteLine("Ну наконец-то подключился... ");
                        
                    }
                    else
                    {
                        if (client != null)
                            if (client.Connected)
                            {
                                //если клиент что-то хочет от сервера
                                if (client_streem.DataAvailable)
                                {
                                    //принял заказ
                                    object quary_from_client = bin_format.Deserialize(client_streem);
                                    //узнал формат заказа
                                    string format = quary_from_client.GetType().ToString();
                                    //ура. нам прислали DataSet
                                    if (format == "System.Data.DataSet")
                                    {
                                        Console.WriteLine("Аха, на сервер передан кусок БД");
                                        data = (DataSet)quary_from_client;
                                        oscar_dataset.Merge(data, false);
                                        oscar_adapter.Update(oscar_dataset);
                                        Console.WriteLine("Файл успешно сохранен");
                                        client_streem.Write(GetByteDataSet(oscar_dataset), 0, GetByteDataSet(oscar_dataset).Length);
                                    }
                                    //блин, опять этот флуд
                                    if (format == "System.String")
                                    {
                                        Console.WriteLine("Опять запрос пришел, опять флудит кто-то");
                                        string str = (string)quary_from_client;
                                        Console.WriteLine(str);
                                    }
                                }
                            }
                    }
                }
            }
JeyKip вне форума Ответить с цитированием
Старый 14.04.2011, 08:15   #8
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Какой кошмар. По "научному" это называется трёхзвенная архитектура. 1 звено - СУБД, 2 звено - сервер, 3 звено - клиент (в двухзвенке соответственно нет посредника между СУБД и клиентом, т.е. сервера). Зачем это заставляют делать студентов я не понимаю. Нормально эту задачу решать долго и сложно, а в таком виде, в каком она есть, она не представляет никакой пользы. Разве что галочку в журнале препод поставит, что лабораторная сдана.
pu4koff вне форума Ответить с цитированием
Старый 10.12.2012, 13:27   #9
Misha666
 
Регистрация: 10.12.2012
Сообщений: 7
По умолчанию

Добрый день. мне очень интересна данная тема, перерыл весь инет но так и не нашел реального примера 3-х звенной архитектуры. можете более подробно написать пример как вы реализовали данную проблему.
Misha666 вне форума Ответить с цитированием
Старый 10.04.2016, 12:03   #10
Владислав7099
Новичок
Джуниор
 
Регистрация: 10.04.2016
Сообщений: 3
Хорошо Как сделать правильно

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Чего за СУБД то использовалась? Если Access, то тупо кидайте файл на сервер, расшаривайте его и подключайтесь к нему из программы. Если более серьезная СУБД, то настраиваете её на сервере, ставите там свою базу, а в программе в ConnectionString меняете путь до базы с указанием этого самого сервера.
Извините что через 5 лет. Но как это расшарить, и что именно сделать надо? и как?
Владислав7099 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Клиент-серверное приложение Mixim C# (си шарп) 1 25.03.2011 01:26
Клиент Серверное приложение BARNEY Общие вопросы Delphi 2 28.10.2010 09:30
Клиент-серверное приложение Куралай_ Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 14.05.2010 10:00
Возможно-ли Клиент-серверное приложение типа Клиент(Pascal) а сервер(CGI)? Demol Работа с сетью в Delphi 1 21.04.2009 16:18
Клиент-серверное приложение veryseldom Работа с сетью в Delphi 8 20.08.2007 19:57